分析
- Promise 就是一个类,在执行这个类时,需要传递一个执行器进去,执行器会立即执行
- Promise 有三种状态
- pending 等待
- fulfilled 成功
- rejected 失败
- Promise 状态变化只能有两种情况:
- pending > fulfilled
- pending > rejected
- 状态一旦确定就不可再更改
- resolve() 和 reject() 用于更改状态
- resolve:fulfilled
- reject:rejected
- then() 方法内部做的事情是判断状态
- 如果状态是成功,调用成功的回调函数
- 如果状态是失败,调用失败的回调函数
- then 成功回调有一个参数,表示成功之后的值;then 失败回调有一个参数,表示失败后的原因
核心代码
const PENDING = 'pending'; // 等待
const FULFILLED = 'fulfilled'; // 成功
const REJECTED = 'rejected'; // 失败
class MyPromise {
constructor(executor) {
try {
executor(this.resolve, this.reject)
} catch (e) {
this.reject(e)
}
}
// promise 状态
status = PENDING;
// 成功之后返回的值
value = undefined;
//失败后返回的原因
reason = undefined;
// 成功回调
successCallback = [];
// 失败回调
failCallback = [];
resolve = value => {
// 如果状态不是等待,阻止程序向下执行
if (this.status !== PENDING) return;
// 将状态更改为成功
this.status = FULFILLED;
// 保存成功之后的值
this.value = value;
// 若成功回调存在,则调用
while (this.successCallback.length) this.successCallback.shift()()
}
reject = reason => {
// 如果状态不是等待,阻止程序向下执行
if (this.status !== PENDING) return;
// 将状态更改为失败
this.status = REJECTED;
// 保存失败后的原因
this.reason = reason;
// 若失败回调存在,则调用
while (this.failCallback.length) this.failCallback.shift()()
}
then(successCallback, failCallback) {
successCallback = successCallback ? successCallback : value => value
failCallback = failCallback ? successCallback : reason => {
throw reason
}
let promise2 = new MyPromise((resolve, reject) => {
if (this.status === FULFILLED) {
// 使代码异步执行,在 promise2 创建完成之后在调用
setTimeout(() => {
try {
let r = successCallback(this.value);
// 判断 r 的值是普通值还是 promise 对象
// 普通值,则直接调用 resolve
// promise 对象,则查看其返回结果,在根据返回的结果,决定调用 resolve 还是 reject
resolvePromise(promise2, r, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
} else if (this.status === REJECTED) {
setTimeout(() => {
try {
let r = failCallback(this.reason);
resolvePromise(promise2, r, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
} else {
// 等待状态,将回调存储起来
this.successCallback.push(() => {
setTimeout(() => {
try {
let r = successCallback(this.value);
resolvePromise(promise2, r, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
});
this.failCallback.push(() => {
setTimeout(() => {
try {
let r = failCallback(this.reason);
resolvePromise(promise2, r, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
});
}
})
return promise2
}
finally(callback) {
return this.then(value => {
return MyPromise.resolve(callback()).then(() => value)
}, reason => {
return MyPromise.resolve(callback()).then(() => {
throw reason
})
})
}
catch(failCallback) {
return this.then(undefined, failCallback)
}
static all(array) {
let result = []
let index = 0
return new MyPromise((resolve, reject) => {
function addData(key, value) {
result[key] = value
index++
if (index === array.length) {
resolve(result)
}
}
for (let i = 0; i < array.length; i++) {
let current = array[i];
if (current instanceof MyPromise) {
// promise 对象
current.then(value => addData(i, value), reason => reject(reason))
} else {
// 普通值
addData(i, array[i])
}
}
})
}
static resolve(value) {
if (value in MyPromise) return value;
return new MyPromise(resolve => resolve(value))
}
}
function resolvePromise(originPromise, x, resolve, reject) {
// 判断返回的是否为 promise 对象本身,是则直接报错,避免 promise 的循环调用
if (originPromise === x) {
return reject(new TypeError('Chaining cycle detected for promise #<Promise>'))
}
if (x instanceof MyPromise) {
// promise 对象
x.then(resolve, reject)
} else {
// 普通值
resolve(x)
}
}
module.exports = MyPromise;