内置属性status的流转:初始化(resolve、reject)、then、catch。并记录value和reason
class Promise {
constructor(executor) {
// 更新状态和值。执行回调函数
this.state = "pending";
this.value = undefined;
this.handlers = [];
const resolve = (value) => {
if (this.state === "pending") {
this.state = "fulfilled";
this.value = value;
this.handlers.forEach((handler) => handler.onFulfilled(value));
}
};
const reject = (reason) => {
if (this.state === "pending") {
this.state = "rejected";
this.value = reason;
this.handlers.forEach((handler) => handler.onRejected(reason));
}
};
try {
executor(resolve, reject);
} catch (error) {
reject(error);
}
}
then(onFulfilled, onRejected) {
// 返回一个Promise。定义个执行函数(resolve\reject\then)。下面就是根据三种状态去执行(有回调执行回调,没有就执行默认的,如果是pending就缓存执行方法)。
return new Promise((resolve, reject) => {
const handle = (handler) => {
try {
const result = handler(this.value);
if (result instanceof Promise) {
result.then(resolve, reject);
} else {
resolve(result);
}
} catch (error) {
reject(error);
}
};
if (this.state === "pending") {
this.handlers.push({
onFulfilled: (value) => {
if (typeof onFulfilled === "function") {
handle(onFulfilled);
} else {
resolve(value);
}
},
onRejected: (reason) => {
if (typeof onRejected === "function") {
handle(onRejected);
} else {
reject(reason);
}
},
});
} else if (this.state === "fulfilled") {
if (typeof onFulfilled === "function") {
handle(onFulfilled);
} else {
resolve(this.value);
}
} else if (this.state === "rejected") {
if (typeof onRejected === "function") {
handle(onRejected);
} else {
reject(this.value);
}
}
});
}
catch(onRejected) {
// then只有reject
return this.then(null, onRejected);
}
static resolve(value) {
return new Promise((resolve) => {
resolve(value);
});
}
static reject(reason) {
return new Promise((resolve, reject) => {
reject(reason);
});
}
static all(promises) {
return new Promise((resolve, reject) => {
const results = [];
let finishedCount = 0;
promises.forEach((promise, index) => {
promise.then((value) => {
results[index] = value;
finishedCount++;
if (finishedCount === promises.length) {
resolve(results);
}
}).catch((reason) => {
reject(reason);
});
});
});
}
static race(promises) {
return new Promise((resolve, reject) => {
promises.forEach((promise) => {
promise.then(resolve).catch(reject);
});
});
}
}