一、基础功能描述
错误处理
- executor中的错误
- then 第一个成功回调中的错误
- then 第二个失败回调中的错误
- 异步中的错误处理
二、代码实现
const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'class MPromise {
constructor(executor){
try{
executor(this.resolve, this.reject)
} catch (e) {
this.reject(e)
}
}
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()()
}
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()()
}
then(successCallback, failCallback) {
let promise2 = new MPromise((resolve, reject) => {
// 状态判断
// 同步: 一次或者多次都直接执行
if(this.status == FULFILLED) {
setTimeout(()=>{ // 如果不用setTimeout,此时获取不到promise2
try {
// then 方法的返回值x,是一个普通值
let x = successCallback(this.value)
// 如果是一个普通值,直接调用resolve
// 如果是一个promise对象,查看promise对象的返回结果,根据返回的结果,决定是调用resolve还是reject
resolvePromise(promise2, x, resolve, reject) // 如果不用setTimeout,此时获取不到promise2
} catch (e) {
reject(e)
}
})
} else if(this.status == REJECTED){
// 同步: 一次或者多次都直接执行
setTimeout(()=>{ // 如果不用setTimeout,此时获取不到promise2
try {
// then 方法的返回值x,是一个普通值
let x = failCallback(this.reason)
// 如果是一个普通值,直接调用resolve
// 如果是一个promise对象,查看promise对象的返回结果,根据返回的结果,决定是调用resolve还是reject
resolvePromise(promise2, x, resolve, reject) // 如果不用setTimeout,此时获取不到promise2
} catch (e) {
reject(e)
}
})
} else {
// 此时说明 状态修改是异步的,需要将成功失败的回调存储起来
// this.successCallback.push(successCallback)
// this.failCallback.push(failCallback)
// 返回值和错误处理
this.successCallback.push(() => {
setTimeout(()=>{ // 如果不用setTimeout,此时获取不到promise2
try {
// then 方法的返回值x,是一个普通值
let x = successCallback(this.value)
// 如果是一个普通值,直接调用resolve
// 如果是一个promise对象,查看promise对象的返回结果,根据返回的结果,决定是调用resolve还是reject
resolvePromise(promise2, x, resolve, reject) // 如果不用setTimeout,此时获取不到promise2
} catch (e) {
reject(e)
}
})
})
this.failCallback.push(() => {
setTimeout(()=>{ // 如果不用setTimeout,此时获取不到promise2
try {
// then 方法的返回值x,是一个普通值
let x = failCallback(this.reason)
// 如果是一个普通值,直接调用resolve
// 如果是一个promise对象,查看promise对象的返回结果,根据返回的结果,决定是调用resolve还是reject
resolvePromise(promise2, x, resolve, reject) // 如果不用setTimeout,此时获取不到promise2
} catch (e) {
reject(e)
}
})
})
}
});
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)
}
}
let pro = new MPromise((res, rej)=>{
// throw new Error('executor error')
// res('成功的值')
rej('失败原因')
})
// pro.then(value=> {
// throw new Error('then error')
// return 100
// }, (reason) => {
// console.log(reason)
// })
// .then(value=> {
// console.log(value)
// }, (reason) => {
// console.log(reason, "then")
// })
pro.then(value=> {
// throw new Error('then error')
return 100
}, (reason) => {
throw new Error('then error')
console.log(reason)
return 100
})
.then(value=> {
console.log(value)
}, (reason) => {
console.log(reason, "then")
})