当前位置: 首页 > Web前端 > JavaScript

Promise源码渐进解读(二)

时间:2023-03-27 11:10:50 JavaScript

关注前端小鱼,阅读更多原创技术文章回顾:Promise源码渐进解读(一)完整代码+注释,可以阅读Promise。Resolvevalue*/Promise.resolve=function(value){/*如果解析值的constructor属性指向Promise构造函数(即解析值是一个Promise实例)*/if(value&&typeofvalue==='object'&&value.constructor===Promise){returnvalue//返回这个Promise实例}/*解析值不是Promise实例,返回一个新的Promise实例并调用其成功回调,参数为resolutionvalue*/returnnewPromise(function(resolve){resolve(value)})}调用Promise.resolve(),相当于newPromise(resolve=>{resolve()}),参数为分辨率值。如果参数是Promise对象,则返回该对象Promise.reject-源码/**Promise构造函数的reject属性,指向函数*参数值:拒绝原因*/Promise.reject=function(value){/*返回一个新的Promise实例并调用它的失败回调,参数为拒绝原因*/returnnewPromise(function(resolve,reject){reject(value)})}callsPromise.reject,即相当于newPromise(resolve=>{reject()}),参数不同于Promise.resolve()作为拒绝原因,即使参数是一个Promise对象,也作为一个整体作为新Promise失败回调的拒绝原因。Promise.resolve&Promise.reject-阶段测试Promise.resolve和Promise.reject实际上是newPromise封装,注意参数为Promise实例时的结果差异Promise.resolve(3)//'resolve:3',resolve的值为基本类型/*selfisPromise{_state:1,_handled:false,_value:3,_deferreds:[]}*/Promise.resolve({val:3})//'resolve:[objectObject]',解析后的值是一个普通对象/*self是一个Promise{_state:1,_handled:false,_value:{val:3},_deferreds:[]}*/Promise.resolve(Promise.resolve(3))//'resolve:3',resolve值为Promise实例/*selfisPromise{_state:1,_handled:false,_value:3,_deferreds:[]}*/Promise.resolve({//解析后的值是thenableobjectvalue:3,then:function(){console.log(this)//{value:3,then:[Function:then]},this指向解析值本身console.log(this.value)//3},})Promise.reject(3)//'reject:3',拒绝原因是基本类型/*selfisPromise{_state:2,_handled:false,_value:3,_deferreds:[]}*/Promise.reject(Promise.resolve(3))//'reject:[objectObject]',拒绝原因是关于Instance的(这里区别于Promise.resolve())/*selfisPromise{_state:2,_handled:false,_value:Promise{_state:1,_handled:false,_value:3,_deferreds:[]},_deferreds:[]}*/Promise.\_immediateFn-源码/**Promise构造函数的_immediateFn属性,指向函数*参数fn:要执行的方法(**注意:是异步调用**)*/varsetTimeoutFunc=setTimeoutvarsetImmediateFunc=typeofsetImmediateFunc=typeofsetImmediate!=='undefined'?setImmediate:null//判断浏览器是否有setImmediate方法Promise._immediateFn=typeofsetImmediateFunc==='function'//判断setImmediateFunc是否为函数对象?function(fn){setImmediateFunc(fn)//异步调用fn方法(立即)}:function(fn){setTimeoutFunc(fn,0)//异步调用fn方法(0毫秒后)}取决于浏览器是否有一个setImmediate方法,方向不同但目标相同,都是异步执行传入方法Promise.\_unhandledRejectionFn-源代码/**Promise构造函数的_unhandledRejectionFn属性,指向函数*参数err:reasonforrejection*/Promise._unhandledRejectionFn=function_unhandledRejectionFn(err){if(typeofconsole!=='undefined'&&console){console.warn('PossibleUnhandledPromiseRejection:',err)//浏览器给出警告}}封装:回调失败时,浏览器给出警告finale()-测试代码更新手写测试finale()方法,添加浏览器警告,使其更贴近源码,方便阶段测试/**finale()方法测试*参数eterself:(termcontract)instance*/functionfinale(self){//console.log(self)//if(self._state===1){//console.log('resolve:'+self._value)//}elseif(self._state===2){//console.log('reject:'+self._value)//}elseif(self._state===3){//console.log('resolvevalueisPromise')//}/*if_state的值为2(失败回调),_deferreds数组的长度为0,则会给出警告*/if(self._state===2&&self._deferreds.length===0){/***调用Promise构造函数的_immediateFn方法*参数fn:要执行的w??arning方法*/Promise._immediateFn(function(){/*如果还没有处理,会给出warning*/if(!self._handled){/***调用Promise构造函数的._unhandledRejectionFn方法*参数self._value:拒绝原因*/Promise._unhandledRejectionFn(self._value)}})}}如果是失败回调(rejectedcontract),而_deferreds数组的长度为0,则会给出警告。_deferreds数组的长度由Promise.reject()后面是否有catch决定。详情见后续浏览器警告——phasetestnewPromise((resolve,reject)=>{reject(2)//PossibleUnhandledPromiseRejection:2})Promise。reject(3)//可能未处理的Promise拒绝:3Promise.resolve(Promise.reject(4))//可能未处理的承诺拒绝:4Promise.reject(Promise.reject(5))//可能未处理的承诺拒绝:Promise{_state:2,_handled:false,_value:5,_deferreds:[]}实现结果总结Promise.resolve和Promise.reject封装了新的Promise。如果Promise.resolve的参数是一个合约,返回合约失败的回调会在浏览器中临时给出一个警告。截至本节代码→