美文网首页
async 函数的实现原理

async 函数的实现原理

作者: wdapp | 来源:发表于2020-02-25 20:54 被阅读0次

基本概念

ES2017 标准引入了 async 函数,使得异步操作变得更加方便。

async 函数是什么?一句话,它就是 Generator 函数的语法糖。

前文有一个 Generator 函数,依次读取两个文件。

const fs = require('fs');

const readFile = function (fileName) {
  return new Promise(function (resolve, reject) {
    fs.readFile(fileName, function(error, data) {
      if (error) return reject(error);
      resolve(data);
    });
  });
};

const gen = function* () {
  const f1 = yield readFile('/etc/fstab');
  const f2 = yield readFile('/etc/shells');
  console.log(f1.toString());
  console.log(f2.toString());
};

上面代码的函数gen可以写成async函数,就是下面这样。

const asyncReadFile = async function () {
  const f1 = await readFile('/etc/fstab');
  const f2 = await readFile('/etc/shells');
  console.log(f1.toString());
  console.log(f2.toString());
};

一比较就会发现,async函数就是将 Generator 函数的星号(*)替换成async,将yield替换成await,仅此而已。

async函数对 Generator 函数的改进,体现在以下四点。

(1)内置执行器。

Generator 函数的执行必须靠执行器,所以才有了co模块,而async函数自带执行器。也就是说,async函数的执行,与普通函数一模一样,只要一行。

asyncReadFile();

上面的代码调用了asyncReadFile函数,然后它就会自动执行,输出最后结果。这完全不像 Generator 函数,需要调用next方法,或者用co模块,才能真正执行,得到最后结果。

(2)更好的语义。

async和await,比起星号和yield,语义更清楚了。async表示函数里有异步操作,await表示紧跟在后面的表达式需要等待结果。

(3)更广的适用性。

co模块约定,yield命令后面只能是 Thunk 函数或 Promise 对象,而async函数的await命令后面,可以是 Promise 对象和原始类型的值(数值、字符串和布尔值,但这时会自动转成立即 resolved 的 Promise 对象)。

(4)返回值是 Promise。

async函数的返回值是 Promise 对象,这比 Generator 函数的返回值是 Iterator 对象方便多了。你可以用then方法指定下一步的操作。

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

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

相关文章

  • es6解读 - async函数

    async函数返回promise对象 async 函数的实现原理 所有的async函数都可以写成上面的第二种形式,...

  • JS async 函数深究

    实现原理 async 函数的实现原理,就是将 Generator 函数和自动执行器,包装在一个函数里。 执行顺序问...

  • async/await 整理总结

    参考:红宝书 es6入门 async async 函数的实现原理,就是将 Generator 函数和自动执行器,包...

  • async函数实现原理

    async函数原理是generator和promise,其中最重要的一个核心方法是co函数 co函数 原版是tj所...

  • async 函数的实现原理

    基本概念 ES2017 标准引入了 async 函数,使得异步操作变得更加方便。 async 函数是什么?一句话,...

  • async、await

    async、await 的特点,优点和缺点,await 的原理是什么? 一个函数如果加上 async 那么该函数就...

  • async-await 网上看到的记录

    一、走进Async-await原理1、原理1async函数返回一个 Promise 对象,可以使用then方法添加...

  • es6

    1、箭头函数的作用是什么 2、promise的作用和实现原理 3、async和promise的区别 4、let,c...

  • async 函数

    含义 基本用法 语法 async 函数的实现原理 与其他异步处理方法的比较 实例:按顺序完成异步操作 异步遍历器

  • promise generator async

    async: async函数是Generator函数的语法糖,是ES7实现的标准,将Generator的星号换成a...

网友评论

      本文标题:async 函数的实现原理

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