一、基础功能描述
then方法可以链式调用, then返回的是一个promise,这个promise不能是then方法本身的这个promise,因为这样会陷入死循环
要把上一个then回调的返回值(return的值,分两种情况:promise和非promise)传递给下一个then方法的回调函数。
then回调返回值是一个promise时(即: return的值),不能是then方法本身的这个promise。
•返回promise和非promise
let pro = new MPromise((res, rej)=>{
res('成功的值')
})
pro.then(value=> {
console.log(value)
return 100
}).then(value=> {
console.log(value)
return new MPromise((resolve, reject) => {
resolve('返回的是promise')
})
}).then(value=> {
console.log(value)
})
• then回调返回值是一个promise(即: return的值)是then方法本身的这个promise
var promise = new Promise(function(resolve,reject){
resolve(100)
})
let p1 = promise.then(function(value){
console.log(value);
// 此时行不通,报错 Chaining cycle detected for promise #<Promise>
return p1
})
p1.then((value)=>{
console.log(value)
},(err)=>{
// 获取失败原因
console.log(err)
})
二、 代码实现
const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'
class MPromise {
constructor(executor){
executor(this.resolve, this.reject)
}
status = PENDING
// 成功后的值
value = undefined
//失败后的原因
reason = undefined
// 为了支持异步修改状态
// 成功回调
successCallback = []
// 失败回调
failCallback = []
// resolve 和 reject都是箭头函数。
// 因为在使用的过程中,直接调用,this指向的是window或者undefined,要让它指向MPromise的实例对象,所以此时应该 使用箭头函数
resolve = (value) => { // value成功后的值
// 状态一旦修改后不能再更改
if(this.status != PENDING) return
this.status = FULFILLED
this.value = value
// 异步:判断成功回调是否存在,如果存在调用
// this.successCallback && this.successCallback(this.value)
while(this.successCallback.length) this.successCallback.shift()(this.value)
}
reject = (reason) => { // reason失败后的原因
// 状态一旦修改后不能再更改
if(this.status != PENDING) return
this.status = REJECTED
this.reason = reason
// 异步:判断失败回调是否存在,如果存在调用
// this.failCallback && this.failCallback(this.reason)
while(this.failCallback.length) this.failCallback.shift()(this.reason)
}
then(successCallback, failCallback) {
let promise2 = new MPromise((resolve, reject) => {
// 状态判断
// 同步: 一次或者多次都直接执行
if(this.status == FULFILLED) {
setTimeout(()=>{ // 如果不用setTimeout,此时获取不到promise2
// then 方法的返回值x,是一个普通值
let x = successCallback(this.value)
// 如果是一个普通值,直接调用resolve
// 如果是一个promise对象,查看promise对象的返回结果,根据返回的结果,决定是调用resolve还是reject
resolvePromise(promise2, x, resolve, reject) // 如果不用setTimeout,此时获取不到promise2
})
} else if(this.status == REJECTED){
// 同步: 一次或者多次都直接执行
failCallback(this.reason)
} else {
// 此时说明 状态修改是异步的,需要将成功失败的回调存储起来
this.successCallback.push(successCallback)
this.failCallback.push(failCallback)
}
});
return promise2
}
}
function resolvePromise(promise2, x, resolve, reject){
// 判断 返回的promise 是否等于 then方法本身的promise,如果等于直接报错
if(promise2 == x) {
return reject(new TypeError('Chaining cycle detected for promise #<Promise>'))
}
if(x instanceof MPromise) {
// 返回的是promise
// x.then(value=> resolve(value), reason => reject(reason)) 等价于
x.then(resolve, reject)
} else {
// 普通值
resolve(x)
}
}