关注前端小鱼,阅读更多原创技术文章回顾:Promise源码渐进解读(一)回顾:Promise源码渐进解读(二)回顾:Promise源码渐进解读(三)完整代码+注意,您可以阅读更多内容以进行比较Athenconcatenation-剩余问题/*尚未实现:不少于2.then()链调用*/newPromise((resolve,reject)=>{resolve(3)})。then((res)=>{/*调用第一个then时,prom为当前then之前返回的合约实例,即resolved合约实例,resolved值为3.PrintselfasPromiseinhandle(){_state:1,_handled:true,_value:3,_deferreds:[]}将继续异步执行处理程序*/returnres}).then((res)=>{/*当第二个then被调用时,prom是当前then之前返回的合约实例是第一个then返回的prom,是一个新的cr吃了和未解决的合同实例。将当前then中生成的Handler实例放入当前then之前返回的合约实例的_deferreds数组中,然后暂停并返回打印selfinhandle()asPromise{_state:0,_handled:false,_value:undefined,_deferreds:[Handler{...}]}*/console.log(res)//不打印res,第二个then及后续的handlers还没有实现})多个then链调用时,从第二个then开始,之前返回的Promise实例都是pending状态的空合约实例,所以将Handler实例放入之前返回的Promise实例的_deferreds数组中。本节将详细讲解handle()和finale()方法,重点讲解Promise实例的_deferreds数组放入Handler实例后的操作。应该反复看handle()-源码终于到了handler()的源码!其实只是比上一节的测试代码改进了一些内容而已。我们主要观察多个then的串联(以2为例)/**handle()方法:核心*参数self:之前then()返回的Promise实例*参数deferred:本次创建的Handler实例*/functionhandle(self,deferred){//console.log(self,'handle')//console.log(deferred)/*deferred是创建的Handler实例Handler{onFulfilled:[Function(anonymous)],//onFulfilledhandler,nullifnotonRejected:[Function(anonymous)],//onRejectedhandler,nullifnonepromise:Promise{//promise属性指向一个新的Promise实例_state:0,_handled:false,_value:undefined,_deferreds:[]}}*//*如果返回的合约实例的解析值为promise类型,_state=3*/while(self._state===3){self=self._value//将解析值赋给返回的合约Example//console.log(self)}/*如果_state=0,现货合约实例处于挂起状态(onResolve或onReject处理程序尚未执行)*//*当链被调用时,secondorlaterthen()之前返回的Promise实例总是一个新的Promise实例,它的_state值为0*/if(self._state===0){self._deferreds.push(deferred)//把Handler实例onthen()之前返回的Promise实例的_deferreds数组,由于前一个Handler实例的promise指向前一个Promise实例,因此前一个Handler实例也会相应受到影响//console.log(self,'push')/*Promise{_state:0,_handled:false,_value:undefined,_deferreds:[Handler{onFulfilled:[Function(anonymous)],onRejected:[Function(anonymous)],promise:[Promise]}]}*/return//这里同步执行暂停,等待异步执行(在上一个Promise的then中执行onResolve)}/*如果不是以上情况,则将当前promise._handled标记为true*/self._handled=true//console.log(self)/**通过事件循环异步处理回调*注意:这里的事件是异步执行的,第二个then会先于这里的方法执行*/Promise._immediateFn(function(){//console.log(deferred,'_immediateFn')//注意:当.then()不少于2个时,上一个.then()生成的Handler实例会有一个promisePromise实例的_deferredspointed指向问题所在(后面的.then()包含onFulfilled或onRejected回调函数,_deferreds不再指向空数组,而是指向包含后者Handler实例的数组)varcb=self._state===1?deferred.onFulfilled:deferred.onRejected//根据最后一次then()之前Promise强度的_state获取onFulfilled或者onRejected处理函数//console.log(cb)/*如果没有onFulfilled或者onRejected回调函数,然后携带当前_value值等待下一个Promise对象的回调*/if(cb===null){//console.log(deferred.promise,self._value);(self._state===1?resolve:reject)(deferred.promise,self._value)/***resolve()或reject方法:等待下一个Promise对象的回调*参数deferred.promise:Handler实例的promise,指向上一个then()的Promise实例*参数self._value:上一个then()之前返回的Promise实例的_value属性值*///resolve(deferred.promise,self._value)//reject(deferred.promise,self._value)return}/*如果有onFulfilled或onRejected回调函数,执行自己的回调*/varrettry{/***cb()方法:执行onFulfilled或onRejectedhandler*参数self._value:returnedbeforethen()Promise实例的解析值/拒绝原因*/ret=cb(self._value)//执行回调并将返回值赋给ret}catch(e){/***reject()方法:处理下一个catch的回调方法*参数deferred.promise:创建的Handler实例的promise属性,指向新的Promise实例*参数e:错误信息*/reject(deferred.promise,e)return}/***resolve()方法:处理下一个then回调方法*参数deferred.promise:Handler实例的promise,指向then()之前的上一个Promise实例*参数ret:执行当前then回调的返回值*///console.log(deferred.promise,ret)resolve(deferred.promise,ret)})}在第二个then之前返回的Promise实例一定是pending状态,所以在第二个then生成的Handler实例会放在第二个then之前返回的Promise实例的_deferreds数组中。还记得Handler构造函数吗?每次then被调用都会生成一个Handler实例,2个then系列会生成2个Handler实例。每个Handler实例的promise指向当前then中生成的Promise实例prom(也就是下一个then之前返回的Promise)实例)但是由于第二个then改变了第二个then之前返回的Promise实例(_deferreds数组是放到Handler实例中),第一个Handler实例也随之变化打开handle()最后的注释console.log(deferred.promise,ret)可以更好的观察到Handler实例的变化。总结起来就是第一个Handler实例的promise属性指向的Promise实例,它的_deferreds数组也被放到了第二个Handler实例中。第二点,在调用handler之后,会再次调用resolve()方法,保证第二个then能拿到第一个then的返回值,记得吗?在resolve()中,为其_state和_value赋值,并调用finale()方法。于是我们来到最终的源码——finale()方法finale()——源码/**finale()方法*参数self:(contract)实例*/functionfinale(self){//console.log(self,'finale')/*如果_state的值为2(Promise执行了reject()方法),并且没有提供回调函数(或者没有实现catch函数),则给出警告*/if(self._状态===2&&self._deferreds.length===0){/***执行Promise构造函数的_immediateFn()方法*参数fn:要执行的w??arning方法*/Promise._immediateFn(function(){/*如果没有处理过,会给出警告*/if(!self._handled){/***执行Promise构造函数的._unhandledRejectionFn()方法*参数self._value:拒绝原因*/Promise._unhandledRejectionFn(self._value)}})}/*循环self._deferreds,为每个项目执行handle()方法*/for(vari=0,len=self._deferreds.length;i
