实现promise的链式调用
第一个例子
这是第一个例子,可以看到,promise的链式调用就是 可以.then().then().then()…这样一直调用下去。说明, .then() 执行完后会返回一个promise。 并且上一个.then返回的值会被resolve然后传给下一个then。
第二个例子
如果上一个.then你没有手动给一个返回值,那么就会将undefined传递给下一个.then
class Promise{
constructor(executor){
this.state = 'pending'
this.value = undefined
this.reason = undefined
this.FulfilledCallbacks = []
this.RejectedCallbacks = []
let resolve = value=>{}
let reject = reason =>{}
try{
executor(resolve,reject)
}catch(err){
reject(err)
}
}
then(onFulfilled,onRejected){
var promise2 = new Promsie((resolve,reject)=>{
if(this.state == 'pending'){
this.FulfilledCallbacks.push(onFulfilled)
this.RejectedCallbacks.push(onRejected)
}
if(this.state === 'fulfilled'){
// 由上面分析可知,.then执行过程中,你可能会手动返回一个东东
let x = onFulfilled(this.value)
// 用一个resolvePromise来处理手动返回的x和内部自动返回的promise2
resolvePromise(promise2,x,resolve,reject)
}
if(this.state === 'rejected'){
let y = onRejected(this.reason)
resolvePromise(promise2,y,resolve,reject)
}
})
return promise2
}
}
看来resolvePromise决定了promise2的状态,那这个resolvePromise要做什么事情呢? 我们先来捋捋。
-
返回一个普通值
,这个普通值nextValue会直接传递给then
看到这里,你想到了nextValue是怎么传递给then的吗?
哈哈,我们注意到
onFulfilled(this.value)
那么,毫无疑问,nextValue就是这里的this.value。而this.value是当前promise2的value。 现在,我们就知道了,resolvePromise的任务就是resolve 当前promise2的,这样下一个then调用的时候就能获得promise2的value。 -
返回的是一个promise
,
比如
显然,返回的是一个promise的话,会先等这个promise先resolve完成,再把这个promise的值想办法给到promise2的value。
那么问题来了, promise2怎么样才能拿到这个promise( x )的value呢?还是这句话
then(onFulfilled,){... onFulfilled(this.calue)}
那么我们就主动调用x.then呗
,
function resolvePromise(promise,x,resolve,reject){
if(x === promise){
return reject(new TypeError('Chaining cycle detected for promise'))
}
// 防止多次调用
let called;
if(x != null && (typeof x == 'object'||typeof x == 'function')){
try{
let then = x.then
// 如果then是函数,就说明x是promise
then.call(x, y=>{
if(called) return
called = true
//resolve(y)
resolvePromise(promise2,y,resolve,reject)
},err=>{
// 无论先调用了resolve,还是reject,另一再调用也没用
if(called) return
called = true
reject(err)
})
}catch(err){
reject(err)
}
}else{
// x是普通值
resolve(x)
}
}
补充
- 如果onFulfilled不是函数则忽略onFullfilled
- then里的回调函数是异步调用的,我们权且用setTimeout来模拟不是
class Promise{
then(onFulfilled,onRejected){
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : (value) => {return value}
onRejected = typeof onRejected === 'function' ? onRejected: throw err
var promise2 = new Promise((resolve,reject)=>{
if(this.state === 'pending'){
this.fulfilledCallbacks.push(()=>{
setTimeout(()=>{
let x= onFulfilled(this.value)
resolvePromise(promise2,x,resolve,reject)
},0)
})
this.rejectedCallbacks.push(()=>{
....
})
}
if(this.state === 'fulfilled'){
setTimeout(()=>{
let x= onFulfilled(this.value)
resolvePromise(promise2,x,resolve,reject)
},0)
}
if(this.state == 'rejected'){
setTimeout(()=>{
try{
let x = onRejected(this.value)
resolvePromise(promise2,x,resolve,reject)
}catch(err){
reject(err)
}
},0)
}
})
return promise2
}
}