function Promise (context) {
// try - catch 抛出 promise 异常
try {
context(resolve, reject)
} catch (error) {
reject(error)
}
let _this = this
_this.status = 'padding' // 等待状态
_this.value = null // 成功结果
_this.reason = null // 失败原因
// 当多个 promise 嵌套时 需要收集
_this.onFulfilledCallbacks = [] // 成功回调函数集合
_this.onRejectedCallbacks = [] // 失败回调函数集合
function resolve (value) {
if (_this.status === 'padding') {
// promise 状态只有为 padding 时,才可以改变
_this.value = value // 保存结果
_this.status = 'fulfilled'
_this.onFulfilledCallbacks.forEach(i => i(value))
}
}
function reject (reason) {
// promise 状态只有为 padding 时,才可以改变
if (_this.status === 'padding') {
_this.value = reason // 保存结果
_this.status = 'rejected'
_this.onRejectedCallbacks.forEach(i => i(reason))
}
}
}
Promise.prototype.then = function (onFulfilled, onRejected) {
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : function (data) {resolve(data)}
onRejected = typeof onRejected === 'function' ? onRejected : function (err) {throw err}
let _this = this
// 不管promise 执行失败还是成功,都要将结果返回给下一个promise
if (_this.status === 'fulfilled') {
// 将执行成功的结果给下一次 promise
return new Promise ((resolve, reject) => {
try {
let x = onFulfilled(_this.value)
x instanceof Promise ? x.then(resolve, reject) : resolve(x)
} catch (error) {
reject(error)
}
})
} else if (_this.status === 'rejected') {
// 将执行失败的结果给下一次 promise
return new Promise((resolve, reject) => {
try {
let x = onRejected(_this.value)
x instanceof Promise ? x.then(resolve, reject) : resolve(x)
} catch (error) {
reject(error)
}
})
} else if (_this.status === 'padding') {
// 当 promise 状态处于 padding 的回调收集
return Promise((resolve, reject) => {
_this.onFulfilledCallbacks.push(() => {
let x = onFulfilled(_this.value)
// 判断 X 是否是promise函数
x instanceof Promise ? x.then(resolve, reject) : resolve(x)
})
_this.onRejectedCallbacks.push(() => {
let x = onRejected(_this.value)
// 判断 X 是否是promise函数
x instanceof Promise ? x.then(resolve, reject) : resolve(x)
})
})
}
// if (_this.status === 'padding') {
// _this.onFulfilledCallbacks.push(onFulfilled)
// _this.onRejectedCallbacks.push(onRejected)
// }
}
let p = new Promise((resolve, reject) => {
console.log('new Promise 执行')
setTimeout(() => {
reject(1);
}, 5000)
})