# 手写Class形式的Promise
- 三个状态,并且状态只能改变一次
- 异步回调的收集
- resolve、reject
/**
* 可借鉴的文章:
* 1. https://segmentfault.com/a/1190000016550260
* 2. https://www.cnblogs.com/wjlbk/p/12633344.html
*/
class Promise {
static PENDING = 'PENDING'; // 等待态
static ONFULFILLED = 'ONFULFILLED'; // 成功态
static ONREJECTED = 'ONREJECTED'; //失败态
constructor(executor) {
this.status = Promise.PENDING;
this.value = void 0;
this.reason = void 0;
this.fulfilledCallbacks = []; // 收集成功的回调
this.rejectedCallbacks = []; // 收集失败的回调
let resolve = (value) => {
if (this.status === Promise.PENDING) { // Promise的状态只能改变一次
this.value = value;
this.status = Promise.ONFULFILLED;
this.fulfilledCallbacks.forEach(fn => fn())
}
}
let reject = (reason) => {
if (this.status === Promise.PENDING) { // Promise的状态只能改变一次
this.reason = reason;
this.status = Promise.ONREJECTED;
this.rejectedCallbacks.forEach(fn => fn());
}
}
try {
executor(resolve, reject);
} catch (error) {
reject(error);
}
}
then(onFulfilled, onRejected) {
return new Promise((resolve, reject) => { // 链式调用的关键,返回一个新的promise
if (this.status === Promise.ONFULFILLED) {
try {
let x = onFulfilled(this.value);
Promise.resolvePromise(x, resolve, reject);
} catch (error) {
reject(error);
}
}
if (this.status === Promise.ONREJECTED) {
try {
let x = onRejected(this.reason);
Promise.resolvePromise(x, resolve, reject);
} catch (error) {
reject(error);
}
}
// 异步的时候,状态还未更改, 需要收集回调
if (this.status === Promise.PENDING) {
this.fulfilledCallbacks.push(() => {
try {
let x = onFulfilled(this.value);
Promise.resolvePromise(x, resolve, reject);
} catch (error) {
reject(error);
}
});
this.rejectedCallbacks.push(() => {
try {
let x = onRejected(this.reason);
Promise.resolvePromise(x, resolve, reject);
} catch (error) {
reject(error);
}
});
}
})
}
/**
* Promise.all()
* 1. 接收一个可迭代的数据结构,且该数据结构的成员是promise对象。
* 2. all方法发挥一个promise实例
* 3. 返回的实例的状态有两种情况
* 3.1 第一种:成员都成功态,则成功回调是一个所有成员返回值组成的有顺序的数组
* 3.2 第二种:只要有一个失败态,则第一个失败态的返回值,传递出来。
*/
static all(promiseArr) {
return new Promise((resolve, reject) => {
let result = [];
promiseArr.forEach((promiseItem, index) => {
promiseItem.then(value => {
result[index] = value;
if (result.length === promiseArr.length) { // 决定什么时候resolve
resolve(result);
}
}, error => {
reject(error);
})
})
})
}
/**
* 返回一个promise实例
* 只要有一个状态改变了,就执行回调。
*/
static race(promiseArr) {
return new Promise((resolve, reject) => {
promiseArr.forEach(promiseItem => {
promiseItem.then(value => {
resolve(value);
}, err => {
reject(err);
})
})
})
}
static resolvePromise(x, resolve, reject) {
if ((typeof x === 'object' && x !== null) || typeof x === 'function') {
try {
let then = x.then;
then.call(x, y => {
resolve(y);
}, r => {
reject(r);
})
} catch (error) {
reject(error);
}
} else {
resolve(x);
}
}
}
module.exports = Promise;