前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >async与await的原理揭秘

async与await的原理揭秘

原创
作者头像
挥刀北上
发布2021-12-10 11:54:04
7700
发布2021-12-10 11:54:04
举报
文章被收录于专栏:Node.js开发Node.js开发

async和await是es7语法,在babel中会被转译,我们看一下专一前和转译后的源码:

代码语言:javascript
复制
async function p (){
	await	console.log('xx')
}
p()
async function w (){
	console.log('xf')
}

转译后:

代码语言:javascript
复制
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
  try {
    var info = gen[key](arg);
    var value = info.value;
  } catch (error) {
    reject(error);
    return;
  }
  if (info.done) {
    resolve(value);
  } else {
    Promise.resolve(value).then(_next, _throw);
  }
}

function _asyncToGenerator(fn) {
  return function () {
    var self = this,
      args = arguments;
    return new Promise(function (resolve, reject) {
      var gen = fn.apply(self, args);
      function _next(value) {
        asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
      }
      function _throw(err) {
        asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
      }
      _next(?developer/article/1916818/undefined);
    });
  };
}

function p() {
  return _p.apply(this, arguments);
}

function _p() {
  _p = _asyncToGenerator(function* () {
    yield console.log("xx");
  });
  return _p.apply(this, arguments);
}

p();

function w() {
  return _w.apply(this, arguments);
}

function _w() {
  _w = _asyncToGenerator(function* () {
    console.log("xf");
  });
  return _w.apply(this, arguments);
}

先解读下p函数,运行p函数就是运行_p函数,运行_p函数会返回里面的_asyncToGenerator函数。

_asyncToGenerator这个函数里面包了一个function*也就是生成器函数,通俗的说,就是将p函数给造成了function*函数。

再来仔细看下这个函数干了啥,这个函数返回一个函数,而这个返回的函数执行会返回一个传入的fn的返回值也就是那个生成器函数的返回值,这个生成器返回值第一次是这个生成器,第二次是它的yield语句,把返回结果做成gen,相当于

代码语言:javascript
复制
function * myfunc(){
	yield console.log('myfunc')
}
gen = myfunc()
gen['next'](参数)//后面函数调用即可打印函数里yield语句

然后运行它里面定义的asyncGeneratorStep函数。

这个函数就比较简单了,注意上面例子的那段话,它就是用trycatch试着运行它的next,也就是function的yield,生成器函数会有done属性,如果完成了done就是true,如果没完,把返回值利用promise.resolve包裹起来递归。

再来看一下w函数,也就是没有加上await的在function*的生成器函数里就会以正常代码存在,如果有yield穿插,看在yield的什么位置,也就是看await的位置。

最后再梳理下整个过程,运行p函数>运行_p返回内部_p运行结果——也就是个递归Promise对象,这个对象会自动执行生成器yield,直到运行完。

async和await确实也算是Promise的语法糖,但实际是promise包裹了generator的语法糖。 源码中使用的特殊技巧: 这个Promise包裹的非常特别,是一个递归一直next直到没有yield才进行resolve的promise,如果下面还有yield,那么就调用Promise.resolve来递归。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
http://www.vxiaotou.com