You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
// Promsie的三种状态varPENDING=0;varFULFILLED=1;varREJECTED=2;varPromise=function(resolver){if(!isFunction(resolver)){thrownewError("resolver must be a function");}this.state=PENDING;this.value=undefined;this.queue=[];safelyResolveThen(this,resolver);};
上面是一个Promise的构造函数,state用来存储promise实例中的状态,初始默认为PENDING,value用来存储resolver的返回值,当 state 是 FULFILLED 时存储返回值,当 state 是 REJECTED 时存储错误。queue是个数组用来存放回调事件。看下safelyResolveThen函数
本文仅是阐述个人的一些理解,如有不对的地方,请指正
关于Promise
现在主流的Promise有很多,个人用过的有Q,bluebird等,有兴趣的可以了解,性能和写法也相差很多。
Promise规范有很多,现在最流行的是Promise/A+规范,ES6也是采用这个规范,具体可以参考:
Promises/A+规范
虽然规范很多,刨去一些细节,最核心的部分总结下来有以下几点:
怎么实现一个简单的Promise
想看源码的可以直接戳这里,里面加了些个人理解的注释。
Promise是一个类对象,在ES6中我们可以称为类,需要用new来实例化,简化下来(去除Promise.all和Promise.race等),一个最最简单的Promise需要有以下几个api:
下面就具体一步步实现每个函数内部的一些功能
上面是一个Promise的构造函数,state用来存储promise实例中的状态,初始默认为PENDING,value用来存储resolver的返回值,当 state 是 FULFILLED 时存储返回值,当 state 是 REJECTED 时存储错误。queue是个数组用来存放回调事件。看下safelyResolveThen函数
顾名思义,此函数存在的意义就是安全的执行then函数,then中的两个参数就是resolve之后执行的函数和reject掉之后执行的函数,主要有下面3个作用👇:
接下来看下doResolve和doReject函数
doResolve和doReejct主要是来改变promise实例中的state和value,即promise实例中内部的状态从PENDING =>FULFILLED或者PENDING =>REJECTED并且执行回调队列中queue对应的回调函数,并且返回自身。
getThen是一个辅助函数,如果返回值是一个promise对象的话,拿到then函数并且改写this的指向:
规范中规定:如果 then 是函数,将 x(这里是 obj) 作为函数的 this 调用。
doResolve和doReject中最后会执行queue中的回调函数
queueItem.callRejected(error)
orqueueItem.callFulfilled(value)
,queueitem也是一个对象,是下面构造函数QueueItem实例出的结果有三个参数,promise是一个Promise的实例,因为最上面说到要返回一个新的promise,而后两个参数onFulfilled, onRejected则是then(resolve,reject)中的参数,把上面三个参数统一包装成了一个对象,进入queue队列中。如果对应的函数不存在,则初始化了一个默认的值,以此来兼容值穿透的情况。
值穿透
then中包裹的不是函数,这样就造成了值穿透的情况,这种情况就需要特殊处理一下
unwap函数代码如下:
第一个参数是子 promise,第二个参数是父 promise 的 then 的回调(onFulfilled/onRejected),第三个参数是父 promise 的值(正常值/错误),使用setTimeout来执行异步操作,使用try...catch来捕获异常。
Promise.prototype.then 和 Promise.prototype.catch
Promise.resolve 和 Promise.reject
这样基本上算是实现了一个简单的Promise,只有核心的部分,后续应该还会再加吧!
参考
深入 Promise(一)——Promise 实现详解: https://zhuanlan.zhihu.com/p/25178630
【翻译】Promises/A+规范http://www.ituring.com.cn/article/66566
The text was updated successfully, but these errors were encountered: