大家好,我是小雨小雨,致力于分享有趣的、实用的技术文章。




内容分为翻译和原创,如果有问题,欢迎随时评论或私信,希望和大家一起进步。




分享不易,希望能够得到大家的支持和关注。



前言


async & await 和我们的日常开发紧密相连,但是你真的了解其背后的原理吗?



本文假设你对promise、generator有一定了解。



generator包装

fn内部调用的是_fn,一个私有方法,使用的apply绑定的this,并传入了动态参数。


_fn内调用了_asyncToGenerator方法,由于js调用栈后进先出:



读起来是这样的:fn() => _asyncToGenerator => .mark()




执行是反过来的:.mark() => _asyncToGenerator => fn()



我们先往里看,映入眼帘的是regeneratorRuntime.mark,该方法是generator的polyfill暴露的方法之一,我们去内部(require('regenerator-runtime/runtime'))简单看下这个mark是用来干什么的。


// 立即执行函数,适配commonjs和浏览器
(function (exports) {
// 暴露mark方法
exports.mark = function (genFun) {
// 兼容判断__proto__,处理老旧环境
if (Object.setPrototypeOf) {
Object.setPrototypeOf(genFun, GeneratorFunctionPrototype);
} else {
genFun.__proto__ = GeneratorFunctionPrototype;
// 设置Symbol.toStringTag,适配toString
if (!(toStringTagSymbol in genFun)) {
genFun[toStringTagSymbol] = 'GeneratorFunction';
}
}
// 设置原型
genFun.prototype = Object.create(Gp);
return genFun;
};
})(typeof module === 'Object' ? module.exports : {});

mark做了两个操作,一个是设置genFun的__proto__,一个是设置prototype,可能有人会好奇:



__proto__不是对象上的吗?prototype不是函数上的吗?为啥两个同时应用到一个上面了



这样操作是没问题的,genFun不仅是函数啊,函数还是对象,js中万物皆对象哦。你想想是不是可以通过Function构造函数new出一个函数?


然后开始设置__proto__和prototype,在次之前,我们来简单捋一下原型。


原型


下面是个人理解的一个说法,未查阅v8引擎,但是这样是说得通的。如果有问题,欢迎指出,一起沟通,我也会及时修改,以免误导他人!!!。



首先要知道这三个的概念:搞清对象的原型对象(proto)、构造函数的原型(prototype)、构造方法(constructor)。


方便记忆,只需要记住下面几条即可:



  • prototype是构造函数(注意:构造函数也是对象嗷)上特有的属性,代表构造函数的原型。举个例子:


有一位小明同学(指代构造函数),他有自己的朋友圈子(指代prototype),通过小明可以找到小红(构造函数.prototype.小红),在通过小红的朋友圈子(prototype)还能找到小蓝,直到有一个人(指代null),孑然一身、无欲无求,莫得朋友。


上面这个关系链就可以理解为原型链。



  • __proto__是每一个对象上特有的属性,指向当前对象构造函数的prototype。再举个例子:


小明家里催的急,不就就生了个大胖小子(通过构造函数{小明}创造出对象{大胖小子}),可以说这个大胖小子一出生就被众星捧月,小明的朋友们纷纷表示,以后孩子有啥事需要帮忙找我就成。这就指代对象上的__proto____proto__可以引用构造函数的任何关系。


所以说,代码源于生活~



  • constructor是啥呢,就是一个prototype上的属性,表示这个朋友圈子是谁的,对于小明来说: 小明.prototype.constructor === 小明。所以,当我们进行继成操作的时候,有必要修正一下constructor,不然朋友圈子就乱了~


  • js中函数和对象有点套娃的意思,万物皆对象,对象又是从构造函数构造而来。对于小明来说,就是我生我生我~~



来看两个判断:


proto 指向构造当前对象的构造函数的prototype,由于万物皆对象,对象又是通过构造函数构造而来。故Object通过Function构造而来,所以指向了Function.prototype


console.log(Object.__proto__ === Function.prototype); // => true

proto 指向构造当前对象的构造函数的prototype,由于万物皆对象,对象又是通过构造函数构造而来。故Function通过Function构造而来,所以指向了Function.prototype


console.log(Function.__proto__ === Function.prototype); // => true

有兴趣的朋友可以再看看这篇文章




然后,我们再来看看这张图,跟着箭头走一遍,是不是就很清晰了?


面试官: 说说你对async的理解


相关文章:

  • 2022-12-23
  • 2021-07-15
  • 2022-01-29
  • 2021-08-26
  • 2021-08-28
  • 2022-02-22
  • 2021-12-17
  • 2021-11-16
猜你喜欢
  • 2021-10-12
  • 2021-05-10
  • 2022-12-23
  • 2021-09-18
  • 2021-07-26
  • 2021-11-08
  • 2021-06-30
相关资源
相似解决方案