美文网首页
es6解读 - async函数

es6解读 - async函数

作者: HowlEagle101Div | 来源:发表于2018-02-07 18:00 被阅读0次
    • async函数返回promise对象
          function timeout(ms) {
              return new Promise((resolve) => {
                  setTimeout(resolve, ms);
              });
           }
    
          async function asyncPrint(value, ms) {
              await timeout(ms);
              console.log(value);
          }
    
          asyncPrint('hello world', 50);
    
        由于async函数返回的是 Promise 对象,可以作为await命令的参数。所以,上面的例子也可以写成
    下面的形式:
         async function timeout(ms) {
              await new Promise((resolve) => {
                  setTimeout(resolve, ms);
              });
          }
    
          async function asyncPrint(value, ms) {
              await timeout(ms);
              console.log(value);
          }
    
        asyncPrint('hello world', 50);
    

    async 函数的实现原理

    async 函数的实现原理,就是将 Generator 函数和自动执行器,包装在一个函数里。
    
    async function fn(args) {
      // ...
    }
    
    // 等同于
    
    function fn(args) {
      return spawn(function* () {
        // ...
      });
    }
    

    所有的async函数都可以写成上面的第二种形式,其中的spawn函数就是自动执行器。

    下面给出spawn函数的实现,基本就是前文自动执行器的翻版。

    function spawn(genF) {
      return new Promise(function(resolve, reject) {
        const gen = genF();
        function step(nextF) {
          let next;
          try {
            next = nextF();
          } catch(e) {
            return reject(e);
          }
          if(next.done) {
            return resolve(next.value);
          }
          Promise.resolve(next.value).then(function(v) {
            step(function() { return gen.next(v); });
          }, function(e) {
            step(function() { return gen.throw(e); });
          });
        }
        step(function() { return gen.next(undefined); });
      });
    }
    

    异步遍历

    const asyncIterable = createAsyncIterable(['a', 'b']);
    const asyncIterator = asyncIterable[Symbol.asyncIterator]();
    
    asyncIterator
    .next()
    .then(iterResult1 => {
      console.log(iterResult1); // { value: 'a', done: false }
      return asyncIterator.next();
    })
    .then(iterResult2 => {
      console.log(iterResult2); // { value: 'b', done: false }
      return asyncIterator.next();
    })
    .then(iterResult3 => {
      console.log(iterResult3); // { value: undefined, done: true }
    });
    

    async promise await执行顺序

    • Promise优先于setTimeout宏任务。所以,setTimeout回调会在最后执行。
    • Promise一旦被定义,就会立即执行。
    • Promise的reject和resolve是异步执行的回调。所以,resolve()会被放到回调队列中,在主函数执行完和setTimeout前调用。
    • await执行完后,会让出线程。async标记的函数会返回一个Promise对象
    async function async1(){
      console.log('async1 start')
      await async2()
      console.log('async1 end')
    }
    async function async2(){
      console.log('async2')
    }
    console.log('script start')
    setTimeout(function(){
      console.log('setTimeout') 
    },0)  
    async1();
    new Promise(function(resolve){
      console.log('promise1')
      resolve();
    }).then(function(){
      console.log('promise2')
    })
    console.log('script end')
    

    上述,在Chrome 66和node v10中,正确输出是:

    script start
    async1 start
    async2
    promise1
    script end
    promise2
    async1 end
    setTimeout
    

    相关文章

      网友评论

          本文标题:es6解读 - async函数

          本文链接:https://www.haomeiwen.com/subject/ubeazxtx.html