万字详解JavaScript手写一个Promise_第1页
万字详解JavaScript手写一个Promise_第2页
万字详解JavaScript手写一个Promise_第3页
万字详解JavaScript手写一个Promise_第4页
万字详解JavaScript手写一个Promise_第5页
已阅读5页,还剩28页未读, 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第万字详解JavaScript手写一个Promise目录前言Promise核心原理实现Promise的使用分析MyPromise的实现在Promise中加入异步操作实现then方法的多次调用实现then的链式调用then方法链式调用识别Promise对象自返回捕获错误及then链式调用其他状态代码补充捕获执行器错误捕获then中的报错错误与异步状态的链式调用将then方法的参数变成可选参数Promise.all方法的实现Promise.resolve方法的实现finally方法的实现catch方法的实现完整代码

前言

手写Promise现在已经成了面试的热门内容,但在实际开发中基本都不会去手写一个Promise,但是在面试中各种手写题可能就会遇到一个手写Promise,我们可以尽量提高我们的上限,从而获取更多的工作机会。

Promise核心原理实现

首先我们从使用的角度来分析一下Promise,然后编写一个最简单版本的Promise。

Promise的使用分析

Promise就是一个类,在执行这个类的时候,需要传递一个执行器(回调函数)进去,执行器会立即执行。

Promise中的状态分为三个,分别是:

pending等待fulfilled成功rejected失败

状态的切换只有两种,分别是:

pendingfulfilledpendingrejected

一旦状态发生改变,就不会再次改变:

执行器中的两个参数,分别是resolve和reject,其实就是两个回调函数,调用resolve是从pending状态到fulfilled,调用reject是从状态pending到rejected。传递给这两个回调函数的参数会作为成功或失败的值。Promise的实例对象具有一个then方法,该方法接受两个回调函数,分别来处理成功与失败的状态,then方法内部会进行判断,然后根据当前状态确定调用的回调函数。then方法应该是被定义在原型对象中的。then的回调函数中都包含一个值,如果是成功,表示成功后返回的值;如果是失败就表示失败的原因。

MyPromise的实现

根据我们上面的分析,写出如下代码:

MyPromise.js

//定义所有状态的常量

constPENDING='pending'

constFULFILLED='fulfilled'

constREJECTED='rejected'

//Promise实质上就是一个类,首先创建一个Promise的类

classMyPromise{

//实例化Promise时需要一个回调函数,该回调函数立即执行

constructor(executor){

//在调用executor需要传递两个回调函数,分别是resolve和reject

executor(this.resolve,this.reject)

//Promise的状态

status=PENDING

//记录成功与失败的值

value=undefined

reason=undefined

resolve=(value)={//这里使用箭头函数是为了使其内部的this指向为该实例化后的对象

//形参value表示,调用resolve时传递的参数

//如果当前状态不是pending,就直接跳出该逻辑

if(this.status!==PENDING)return

//将状态修改为成功

this.status=FULFILLED

//将传入的值进行保存

this.value=value

reject=(reason)={//这里使用箭头函数是为了使其内部的this指向为该实例化后的对象

//形参reason表示,调用reject时传递的失败的原因

//如果当前状态不是pending,就直接跳出该逻辑

if(this.status!==PENDING)return

//将状态修改为失败

this.status=REJECTED

//保存失败的原因

this.reason=reason

//then方法的实现

then(onFulfilled,onRejected){

//判断当前状态,根据状态调用指定回调

if(this.status===FULFILLED){

//将成功的值作为参数返回

onFulfilled(this.value)

}elseif(this.status===REJECTED){

//将失败的原因作为参数返回

onRejected(this.reason)

//导出Promise

module.exports=MyPromise

现在我们就来写一段代码验证一下上面的代码

验证resolve:

constMyPromise=require('./myPromise')

letpromise=newMyPromise((resolve,reject)={

resolve('成功')

promise.then(value={

console.log(value);

},reason={

console.log(reason);

/*输出

*/

验证reject:

constMyPromise=require('./myPromise')

letpromise=newMyPromise((resolve,reject)={

reject('失败')

promise.then(value={

console.log(value);

},reason={

console.log(reason);

/*输出

*/

验证状态不可变:

constMyPromise=require('./myPromise')

letpromise=newMyPromise((resolve,reject)={

resolve('成功')

reject('失败')

promise.then(value={

console.log(value);

},reason={

console.log(reason);

/*输出

*/

在Promise中加入异步操作

如果我们的代码中存在异步操作,我们自己写的Promise将毫无用处,

例如下面这段代码:

constMyPromise=require('./myPromise')

letpromise=newMyPromise((resolve,reject)={

setTimeout(resolve,2000,'成功')

promise.then(value={

console.log(value);

},reason={

console.log(reason);

})

这段代码2000ms后没有任何输出,为了解决这个问题我们将对自己编写的类进行如下操作:

创建两个实例方法用于存储我们传入的成功与失败的处理逻辑。为then方法添加状态为pending时的处理逻辑,这时将传递进来的属性保存到实例上。在成功或者失败时调用相应的传递进来的回调函数(实例属性存在函数的情况下)。

实现代码如下:

//MyPromise.js

constPENDING='pending'

constFULFILLED='fulfilled'

constREJECTED='rejected'

classMyPromise{

constructor(executor){

executor(this.resolve,this.reject)

status=PENDING

value=undefined

reason=undefined

//存储成功与失败的处理逻辑

onFulfilled=undefined

onRejected=undefined

resolve=(value)={

if(this.status!==PENDING)return

this.status=FULFILLED

this.value=value

//如果将状态修复为成功,调用成功的回调

this.onFulfilledthis.onFulfilled(this.value)

reject=(reason)={

if(this.status!==PENDING)return

this.status=REJECTED

this.reason=reason

//如果将状态修复为失败,调用失败的回调

this.onRejectedthis.onRejected(this.reason)

then(onFulfilled,onRejected){

if(this.status===FULFILLED){

onFulfilled(this.value)

}elseif(this.status===REJECTED){

onRejected(this.reason)

}else{

//表示既不是成功,也不是失败。这个时候保存传递进来的两个回调

this.onFulfilled=onFulfilled

this.onRejected=onRejected

module.exports=MyPromise

这里的this.onFulfilledthis.onFulfilled(this.value)表示如果该属性存在就调用这个方法。

现在我们重新执行一开始上面那一段代码,2s后会成功输出成功。

实现then方法的多次调用

Promise实例中存在要给then方法,允许我们在Promise实例中链式调用,每个then方法还会返回一个Promise实例,

如下图所示:

Promise实例方法then是可以多次进行调用,而我们现在自己封装的却执行调用一次,现在根据新需要来重新改写我们的代码,

实现思路如下:

定义可以存储多个回调的数组,用于存储多个回调函数。如果是同步执行的代码,执行后立即知道执行结果,所以可以直接调用回调函数。如果是异步代码,需要将每次回调函数保存到数组中,然后状态变化时依次调用函数。

实现代码如下:

//MyPromise.js

constPENDING='pending'

constFULFILLED='fulfilled'

constREJECTED='rejected'

classMyPromise{

constructor(executor){

executor(this.resolve,this.reject)

status=PENDING

value=undefined

reason=undefined

//存储成功与失败的处理逻辑

onFulfilled=[]

onRejected=[]

resolve=(value)={

if(this.status!==PENDING)return

this.status=FULFILLED

this.value=value

//如果将状态修复为成功,调用成功的回调

while(this.onFulfilled.length){

//Atotype.shift()用于删除数组第一个元素,并返回

this.onFulfilled.shift()(this.value)

reject=(reason)={

if(this.status!==PENDING)return

this.status=REJECTED

this.reason=reason

//如果将状态修复为失败,调用失败的回调

while(this.onRejected.length){

//Atotype.shift()用于删除数组第一个元素,并返回

this.onRejected.shift()(this.reason)

then(onFulfilled,onRejected){

if(this.status===FULFILLED){

onFulfilled(this.value)

}elseif(this.status===REJECTED){

onRejected(this.reason)

}else{

//表示既不是成功,也不是失败。这个时候保存传递进来的两个回调

this.onFulfilled.push(onFulfilled)

this.onRejected.push(onRejected)

module.exports=MyPromise

这里我们通过数组的shift()方法,该方法删除数组的第一个元素,并返回,返回的这个值正好是一个回调函数,然后调用该函数即可实现该功能。

实现then的链式调用

想要实现then的链式调用,主要解决两个问题:

返回的是一个新的MyPormise实例。then的返回值作为下一次的链式调用的参数。

这里分为两种情况:

直接返回一个值,可以直接作为值使用返回一个新的MyPormise实例,此时就需要判断其状态

实现代码如下:

//MyPromise.js

/*省略的代码同上*/

classMyPromise{

/*省略的代码同上*/

//then方法的实现

then(onFulfilled,onRejected){

//then方法返回一个MyPromise实例

returnnewMyPromise((resolve,reject)={

//判断当前状态,根据状态调用指定回调

if(this.status===FULFILLED){

//将成功的值作为参数返回

//保存执行回调函数的结果

constresult=onFulfilled(this.value)

//如果返回的是一个普通的值,直接调用resolve

//如果是一个MyPromise实例,根据返回的解决来决定是调用resolve,还是reject

resolvePromise(result,resolve,reject)

}elseif(this.status===REJECTED){

//将失败的原因作为参数返回

onRejected(this.reason)

}else{

//表示既不是成功,也不是失败。这个时候保存传递进来的两个回调

this.onFulfilled.push(onFulfilled)

this.onRejected.push(onRejected)

functionresolvePromise(result,resolve,reject){

//判断传递的result是不是MyPromise的实例对象

if(resultinstanceofMyPromise){

//说明是MyPromise的实例对象

//调用.then方法,然后在回调函数中获取到具体的值,然后调用具体的回调

//result.then(value=resolve(value),reason=reject(reason))

//简写

result.then(resolve,reject)

}else{

resolve(result)

module.exports=MyPromise

then方法链式调用识别Promise对象自返回

在Promise中,如果then方法返回的是自己的promise对象,则会发生promise的嵌套,这个时候程序会报错,

测试代码如下:

varpromise=newPromise((resolve,reject)={

resolve(100)

varp1=promise.then(value={

console.log(value)

returnp1

//100

//Uncaught(inpromise)TypeError:Chainingcycledetectedforpromise#Promise

想要解决这个问题其实我们只需要在then方法返回的MyPromise实例对象与then中回调函数返回的值进行比对,如果相同的返回一个reject的MyPromise实例对象,并创建一个TypeError类型的Error。

实现代码如下:

//MyPromise.js

/*省略的代码同上*/

then(onFulfilled,onRejected){

//then方法返回一个MyPromise实例

constpromise=newMyPromise((resolve,reject)={

//判断当前状态,根据状态调用指定回调

if(this.status===FULFILLED){

//这里并不需要延迟执行,而是通过setTimeout将其变成异步函数

//如果不变成异步的话是在函数内获取不到promise的

setTimeout(()={

//将成功的值作为参数返回

//保存执行回调函数的结果

constresult=onFulfilled(this.value)

//如果返回的是一个普通的值,直接调用resolve

//如果是一个MyPromise实例,根据返回的解决来决定是调用resolve,还是reject

resolvePromise(promise,result,resolve,reject)

},0)

}elseif(this.status===REJECTED){

//将失败的原因作为参数返回

onRejected(this.reason)

}else{

//表示既不是成功,也不是失败。这个时候保存传递进来的两个回调

this.onFulfilled.push(onFulfilled)

this.onRejected.push(onRejected)

returnpromise

functionresolvePromise(promise,result,resolve,reject){

//这里修改一下该函数,如果return的Promise实例对象,也就是传入的promise===result的话,说明在promise中return的是当前promise对象。

if(promise===result){

//这里调用reject,并抛出一个Error

//return是必须的,阻止程序向下执行

returnreject(newTypeError('Chainingcycledetectedforpromise#Promise'))

//判断传递的result是不是MyPromise的实例对象

if(resultinstanceofMyPromise){

//说明是MyPromise的实例对象

//调用.then方法,然后在回调函数中获取到具体的值,然后调用具体的回调

//result.then(value=resolve(value),reason=reject(reason))

//简写

result.then(resolve,reject)

}else{

resolve(result)

module.exports=MyPromise

这里then方法中的setTimeout的作用并不是延迟执行,而是为了调用resolvePromise函数时,保证创建的promise存在。

捕获错误及then链式调用其他状态代码补充

到目前为止我们现实的Promise并没有对异常做任何处理,为了保证代码的健壮性,我们需要对异常做一些处理。

捕获执行器错误

现在我们需要对执行器进行异常捕获,如果发生异常,就将我们的状态修改为rejected。

捕获执行器的错误也比较简单,只需要在构造函数中加入try...catch语句就可以,

实现代码如下:

constructor(executor){

try{

//在调用executor需要传递两个回调函数,分别是resolve和reject

executor(this.resolve,this.reject)

}catch(e){

//发生异常调用reject

this.reject(e)

}

测试代码如下:

constMyPromise=require('./myPromise')

letpromise=newMyPromise((resolve,reject)={

thrownewError('执行器错误')

promise.then(value={

console.log(value);

},error={

console.log(error.message);

/*输出

执行器错误

*/

捕获then中的报错

现在我们需要对then中的异常捕获到,并在下一次链式调用中传递到then的第二个函数中,实现的方式也是通过try...catch语句,

示例代码如下:

//then方法的实现

then(onFulfilled,onRejected){

//then方法返回一个MyPromise实例

constpromise=newMyPromise((resolve,reject)={

//判断当前状态,根据状态调用指定回调

if(this.status===FULFILLED){

//这里并不需要延迟执行,而是通过setTimeout将其变成异步函数

//如果不变成异步的话是在函数内获取不到promise的

setTimeout(()={

try{

//将成功的值作为参数返回

//保存执行回调函数的结果

constresult=onFulfilled(this.value)

//如果返回的是一个普通的值,直接调用resolve

//如果是一个MyPromise实例,根据返回的解决来决定是调用resolve,还是reject

resolvePromise(promise,result,resolve,reject)

}catch(error){

reject(error)

},0)

}elseif(this.status===REJECTED){

//将失败的原因作为参数返回

onRejected(this.reason)

}else{

//表示既不是成功,也不是失败。这个时候保存传递进来的两个回调

this.onFulfilled.push(onFulfilled)

this.onRejected.push(onRejected)

returnpromise

}

测试代码如下:

constMyPromise=require('./myPromise')

letpromise=newMyPromise((resolve,reject)={

resolve('成功')

//第一个then方法中的错误要在第二个then方法中捕获到

promise.then(value={

console.log('resolve',value)

thrownewError('then的执行过程中遇到异常')

}).then(null,reason={

console.log(reason.message)

/*输出

resolve成功

then的执行过程中遇到异常

*/

错误与异步状态的链式调用

现在只对成功状态的then进行的链式调用以及错误处理,错误与异步状态未进行处理,其实处理起来也是一样的,

示例代码如下:

//then方法的实现

then(onFulfilled,onRejected){

//then方法返回一个MyPromise实例

constpromise=newMyPromise((resolve,reject)={

//判断当前状态,根据状态调用指定回调

if(this.status===FULFILLED){

//这里并不需要延迟执行,而是通过setTimeout将其变成异步函数

//如果不变成异步的话是在函数内获取不到promise的

setTimeout(()={

try{

//将成功的值作为参数返回

//保存执行回调函数的结果

constresult=onFulfilled(this.value)

//如果返回的是一个普通的值,直接调用resolve

//如果是一个MyPromise实例,根据返回的解决来决定是调用resolve,还是reject

resolvePromise(promise,result,resolve,reject)

}catch(error){

reject(error)

},0)

}elseif(this.status===REJECTED){

//失败的处理同成功处理,只是调用的回调函数不同

setTimeout(()={

try{

constresult=onRejected(this.reason)

resolvePromise(promise,result,resolve,reject)

}catch(error){

reject(error)

},0)

}else{

this.onFulfilled.push((value)={

setTimeout(()={

try{

constresult=onFulfilled(value)

resolvePromise(promise,result,resolve,reject)

}catch(error){

reject(error)

},0)

this.onRejected.push((reason)={

setTimeout(()={

try{

constresult=onRejected(reason)

resolvePromise(promise,result,resolve,reject)

}catch(error){

reject(error)

},0)

returnpromise

}

测试代码如下:

constMyPromise=require('./myPromise')

letpromise=newMyPromise((resolve,reject)={

setTimeout(resolve,2000,'成功')

//第一个then方法中的错误要在第二个then方法中捕获到

promise.then(value={

console.log('resolve',value)

thrownewError('then的执行过程中遇到异常')

}).then(null,reason={

console.log(reason.message)

/*输出

resolve成功

then的执行过程中遇到异常

*/

将then方法的参数变成可选参数

Promise中的then方法其实是两个可以可选参数,如果我们不传递任何参数的话,里面的结果是向下传递的,直到捕获为止,

例如下面这段代码:

newPromise((resolve,reject)={

resolve(100)

.then()

.then()

.then()

.then(value=console.log(value))

//最后一个then输入100

这段代码可以理解为:

newPromise((resolve,reject)={

resolve(100)

.then(value=value)

.then(value=value)

.then(value=value)

.then(value=console.log(value))

所以说我们只需要在没有传递回调函数时,赋值一个默认的回调函数即可。

实现代码如下:

//then方法的实现

then(onFulfilled,onRejected){

//如果传递函数,就是用传递的函数,否则指定一个默认值,用于参数传递

onFulfilled=onFulfilledonFulfilled:value=value

//同理

onRejected=onRejectedonRejected:reason={throwreason}

//then方法返回一个MyPromise实例

constpromise=newMyPromise((resolve,reject)={

//判断当前状态,根据状态调用指定回调

if(this.status===FULFILLED){...

}elseif(this.status===REJECTED){...

}else{...

returnpromise

}

Promise.all方法的实现

关于all()方法的使用,可以参数Promise.all()。简单的说Promise.all()会将多个Promise实例包装为一个Promise实例,且顺序与调用顺序一致,

示例代码如下:

functionp1(){

returnnewPromise((resolve,reject)={

setTimeout(()={

resolve('p1')

},2000)

functionp2(){

returnnewPromise((resolve,reject)={

setTimeout(()={

resolve('p2')

},0)

Promise.all(['a','b',p1(),p2(),'c']).then(result={

console.log(result)

//["a","b","p1","p2","c"]

})

在这段代码中,我们的p1的执行是延迟了2s的,这里如果不使用Promise.all()的话最终顺序是与我们调用不同的。

现在我们来分析一下all()的实现思路:

all()方法可以通过类直接调用,所以是一个静态方法all()方法接收一个数组,数组中的值可以是一个普通值,也可以是一个MyPromise的实例对象return一个新的MyPromise实例对象遍历数组中的每一个值,判断值得类型,如果是一个普通值得话直接将值存入一个数组;如果是一个MyPromise的实例对象的话,会调用then方法,然后根据执行后的状态,如果失败的话调用新的MyPromise实例对象中的rejecte,如果是成功话将这个值存入一个数组存入数组时计数,如果存入的数量达到传入的数组长度,说明调用完毕,执行resolve并将最终的结果数组作为参数返回。

实现代码:

/**

*@description:将多个Promise实例合并为一个Promise实例

*@param{*}arrayPromise或者普通值

*@returns{Promise}

staticall(array){

//用于存放最终结果的数组

letresult=[]

//用于计算当前已经执行完的实例的数量

letcount=0

//最后返回的是一个Promise实例

returnnewMyPromise((resolve,reject)={

/**

*@description:将执行完毕的值加入结果数组,并根据实际情况决定是否调用resolve

*@param{*}result存放结果的数组

*@param{*}index要加入的索引

*@param{*}value要加入数组的值

*@param{*}resolvePromise中的resolve

functionaddResult(result,index,value,resolve){

//根据索引值,将结果堆入数组中

result[index]=value

//执行完毕一个count+1,如果当前值等于总长度的话说明已经执行结束了,可以直接调用resolve,说明已经成功执行完毕了

if(++count===array.length){

//将执行结果返回

resolve(result)

//遍历穿入的数组,每个都执行then方法,获取到最终的结果

array.forEach((p,index)={

//判断p是不是MyPromise的实例,如果是的话调用then方法,不是直接将值加入数组中

if(pinstanceofMyPromise){

p.then(

//成功时将结果直接加入数组中

value={

addResult(result,index,value,resolve)

//如果失败直接返回失败原因

reason={

reject(reason)

else{

addResult(result,index,p,resolve)

}

Promise.resolve方法的实现

关于Promise.resolve()方法的用法可以参考Promise.resolve()与Promise.reject()。

我们实现的思路主要如下:

该方法是一个静态方法该方法接受的如果是一个值就将该值包装为一个MyPromise的实例对象返回,如果是一个MyPromise的实例对象,调用then方法返回。

实现代码如下:

staticresolve(value){

//如果是MyPromise的实例,就直接返回这个实例

if(valueinstanceofMyPromise)returnvalue

//如果不是的话创建一个MyPromise实例,并返回传递的值

returnnewMyPromise((resolve)={

resolve(value)

}

finally方法的实现

关于finally方法可参考finally(),实现该方法的实现代码如下:

finally(callback){

//如何拿到当前的promise的状态,使用then方法,而且不管怎样都返回callback

//而且then方法就是返回一个promise对象,那么我们直接返回then方法调用之后的结果即可

//我们需要在回调之后拿到成功的回调,所以需要把value也return

//失败的回调也抛出原因

//如果callback是一个异步的promise对象,我们还需要等待其执行完毕,所以需要用到静态方法resolve

returnthis.then(value={

//把callback调用之后返回的promise传递过去,并且执行promise,且在成功之后返回value

returnMyPromise.resolve(callback()).then(()=value)

},reason={

//失败之后调用的then方法,然后把失败的原因返回出去。

returnMyPromise.resolve(callback()).then(()={throwreason})

}

测试:

functionp1(){

returnnewMyPromise((resolve,reject)={

setTimeout(()={

resolve('p1')

},2000)

functionp2(){

returnnewMyPromise((resolve,reject)={

reject('p2reject')

p2().finally(

()={

console.log('finallyp2')

returnp1()

).then(

value={

console.log(value)

},reason={

console.log(reason)

//finallyp2

//两秒之后执行p2reject

catch方法的实现

关于catch方法可以参考catch(),实现该方法其实非常简单,只需要在内部调用then方法,不传递第一个回调函数即可,

实现代码如下:

catch(callback){

returnthis.then(null,failCallback)

}

测试如下:

functionp(){

returnnewMyPromise((resolve,reject)={

reject(newError('reject'))

.then(value={

console.log(value)

.catch(reason=console.log(reason))

完整代码

//MyPromise.js

//定义所有状态的常量

constPENDING='pending'

constFULFILLED='fulfilled'

constREJECTED='rejected'

//Promise实质上就是一个类,首先创建一个Promise的类

classMyPromise{

//实例化Promise时需要一个回调函数,该回调函数立即执行

constructor(executor){

try{

//在调用executor需要传递两个回调函数,分别是resolve和reject

executor(this.resolve,this.reject)

}catch(e){

//发生异常调用reject

this.reject(e)

//Promise的状态

status=PENDING

//记录成功与失败的值

value=undefined

reason=undefined

//存储成功与失败的处理逻辑

onFulfilled=[]

onRejected=[]

resolve=(value)={//这里使用箭头函数是为了使其内部的this指向为该实例化后的对象

//形参value表示,调用resolve时传递的参数

//如果当前状态不是pending,就直接跳出该逻辑

if(this.status!==PENDING)return

//将状态修改为成功

this.status=FULFILLED

//将传入的值进行保存

this.value=value

//如果将状态修复为成功,调用成功的回调

//this.onFulfilledthis.onFulfilled(this.value)

while(this.onFulfilled.length){

//Atotype.shift()用于删除数组第一个元素,并返回

this.onFulfilled.shift()(this.value)

reject=(reason)={//这里使用箭头函数是为了使其内部的this指向为该实例化后的对象

//形参reason表示,调用reject时传递的失败的原因

//如果当前状态不是pending,就直接跳出该逻辑

if(this.status!==PENDING)return

//将状态修改为失败

this.status=REJECTED

//保存失败的原因

this.reason=reason

//如果将状态修复为失败,调用失败的回调

//this.onRejectedthis.onRejected(this.reason)

while(this.onRejected.length){

//Atotype.shift()用于删除数组第一个元素,并返回

this.onRejected.shift()(this.reason)

//then方法的实现

then(onFulfilled,onRejected){

//如果传递函数,就是用传递的函数,否则指定一个默认值,用于参数传递

onFulfilled=onFulfilledonFulfilled:value=value

//同理

onRejected=onRejectedonRejected:reason={throwreason}

//then方法返回一个MyPromise实例

constpromise=newMyPromise((resolve,reject)={

//判断当前状态,根据状态调用指定回调

if(this.status===FULFILLED){

//这里并不需要延迟执行,而是通过setTimeout将其变成异步函数

//如果不变成异步的话是在函数内获取不到promise的

setTimeout(()={

try{

//将成功的值作为参数返回

//保存执行回调函数的结果

constresult=onFulfilled(this.value)

//如果返回的是一个普通的值,直接调用resolve

//如果是一个MyPromise实例,根据返回的解决来决定是调用resolve,还是reject

resolvePromise(promise,result,resolve,reject)

}catch(error){

reject(error)

},0)

}elseif(this.status===REJECTED){

//失败的处理同成功处理,只是调用的回调函数不同

setTimeout(()={

try{

constresult=onRejected(this.reason)

resolvePromise(promise,result,resolve,reject)

}catch(error){

reject(error)

},0)

}else{

//表示既不是成功,也不是失败。这个时候保存传递进来的两个回调

//this.onFulfilled.push(onFulfilled)

//this.onRejected.push(onRejected)

this.onFulfilled.push((value)={

setTimeout(()={

try{

constresult=onFulfilled(value)

resolvePromise(promise,result,resolve,reject)

}catch(error){

reject(error)

},0)

this.onRejected.push((reason)={

setTimeout(()={

try{

constresult=onRejected(reason)

resolvePromise(promise,result,resolve,reject)

}catch(error){

reject(error)

},0)

returnpromise

catch(callback){

returnthis.then(null,callback)

finally(callback){

//如何拿到当前的promise的状态,使用then方法,而且不管怎样都返回callback

//而且then方法就是返回一个promise对象,那么我们直接返回then方法调用之后的结果即可

//我们需要在回调之后拿到成功的回调,所以需要把val

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论