Day 66/100 ES6中Async函数的实现原理

写在前面的话

在前端面试中,经常会问到ES6属性的问题

而Async是常考题,里面还有一些演变

今天先分享实现原理~

(一)async 函数是什么?

一句话,它就是 Generator 函数的语法糖。

特点

比Generator的改进

1)内置执行器;

2)更好的语义;

3)更广的适用性;

4)返回值是 Promise。

async函数完全可以看作多个异步操作,包装成的一个 Promise 对象,而await命令就是内部then命令的语法糖。


1、形式Generator函数和执行函数

async function fn(args) {

  // ...

}

等同于

function fn(args) {

  return spawn(function* () {

    // ...

  });

}

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

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

2、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); });

  });

}

3、并发读取远程URL 

这个是常考题(划重点),如何并发发出远程请求;

async function logInOrder(urls) {

  // 并发读取远程URL

  const textPromises = urls.map(async url => {

    const response = await fetch(url);

    return response.text();

  });

// 按次序输出

  for (const textPromise of textPromises) {

    console.log(await textPromise);

  }

}

上面代码中,虽然map方法的参数是async函数,但它是并发执行的,因为只有async函数内部是继发执行,外部不受影响。后面的for..of循环内部使用了await,因此实现了按顺序输出。


参考链接

https://es6.ruanyifeng.com/#docs/async

你可能感兴趣的:(Day 66/100 ES6中Async函数的实现原理)