实现 promise 中 then 办法的链式调用
const PEDDING = 'PEDDING'
const RESOLVE = 'RESOLVE'
const REJECT = 'REJECT'
// promise 有三种状态
const handlePromise = (result,newPromise,resolve, reject)=>{if(result === newPromise){throw new Error('不能返回本人')
}
// 返回的是对象或者办法(也能够是 promise)if(typeof result === 'object' && typeof result !== null || typeof result === 'function'){
// 判断 result 是否有 then 办法
const then = result.then
if(typeof then === 'function'){
// 如果 then 办法是一个 function 默认是 promise
// 调用 call 办法
then.call(result,r=>{
// 持续调用本人,r 就是 then 外面的 res
handlePromise(r,newPromise,resolve, reject)
},e=>{reject(e)
})
}else{resolve(result)
}
}else{
// 返回一般值
resolve(result)
}
}
class NewPromise {
// 初始状态为 PEDDING
status = PEDDING
result = undefined
reason = undefined
// 公布订阅者模式
// 目标是为了实现异步
onResolveArr = []
onRejectArr = []
constructor(exc) {const resolve = (result) => {if (this.status === PEDDING) {
this.result = result
this.status = RESOLVE
// 执行发布者
this.onResolveArr.map((fn) => fn())
}
}
const reject = (reason) => {if (this.status === PEDDING) {
this.reason = reason
this.status = REJECT
// 执行发布者
this.onRejectArr.map((fn) => fn())
}
}
exc(resolve, reject)
}
then(onResolve, onReject) {const newPromise = new NewPromise((resolve, reject) => {if (this.status === RESOLVE) {setTimeout(() => {const result = onResolve(this.result)
handlePromise(result,newPromise,resolve, reject)
}, 0)
}
if (this.status === REJECT) {setTimeout(() => {const result = onReject(this.reason)
handlePromise(result,newPromise,resolve, reject)
}, 0)
}
// 公布订阅者模式
if (this.status === PEDDING) {
// 将订阅者增加到数组外面
this.onResolveArr.push(() => {const result = onResolve(this.result)
handlePromise(result,newPromise,resolve, reject)
})
this.onRejectArr.push(() => {const result = this.onReject(this.reason)
handlePromise(result,newPromise,resolve, reject)
})
}
})
return newPromise
}
}
// let yan = new Promise((resole, reject) => {// resole('闫大爷真帅')
// })
// yan.then(res => {// console.log(res)
// })
let newYan = new NewPromise((resole, reject) => {setTimeout(() => {resole('new 闫大爷真帅')
return '1111'
}, 3000)
})
newYan
.then((res) => {console.log(res)
return {name:'yan'}
})
.then((res) => {console.log(res)
})
console.log(11111111)