promise

promise A+规范

  • Promise 对象的状态: Promise 对象可以处于三种状态之一,分别为 pending(进行中)、fulfilled(已成功)和 rejected(已失败),状态转变只能是从 pending 到 fulfilled 或从 pending 到 rejected。

  • then 方法: Promise 对象必须提供一个 then 方法,用于处理 Promise 对象的状态变化。then 方法接受两个参数,分别是处理成功情况的回调函数和处理失败情况的回调函数。

  • then 方法返回一个新的 Promise 对象:then 方法应该返回一个新的 Promise 对象,以便支持 Promise 链式调用。

  • 错误处理: Promise 对象应该能够捕获并处理异常,可以通过 catch 方法或者在 then 方法的失败回调中处理异常。

  • Promise 对象的值传递: Promise 对象的值可以被传递给后续的 Promise 对象,并且会沿着 Promise 链一直传递下去。

  • Promise 链: 多个 Promise 对象可以形成 Promise 链,一个 Promise 对象的结果可以作为另一个 Promise 对象的输入。

实现

import { isMicroQueue } from "./isMicroQueue.js";
const PENDING = "pending";
const FULFILLED = "fulfilled";
const REJECTED = "rejected";

//判断是否符合promise A+规范
const isPromise = (obj) =>
!!(obj && typeof obj === "object" && typeof obj.then === "function");

class MyPromise {
#state = PENDING;
#value = undefined;
#callbacks = [];
constructor(executor) {
try {
//执行器
executor(this.#resolve.bind(this), this.#reject.bind(this));
} catch (error) {
//执行环境中遇到错误直接返回失败
this.#reject(error);
throw error;
}
}
#resolve(value) {
this.#changeState(FULFILLED, value);
}
#reject(value) {
this.#changeState(REJECTED, value);
}
#changeState(state, value) {
//状态只能从pending -> 成功或失败
if (!this.#isPending(this.#state)) return;
this.#state = state;
this.#value = value;
this.#runCallbacks();
}
//收集回调
#pushCallback(executor, state, resolve, reject) {
this.#callbacks.push({
executor,
state,
resolve,
reject,
});
}
//执行回调
#runCallbacks() {
//未敲定状态
if (this.#isPending(this.#state)) return;
//每次执行一个回调,执行完毕从队列删除
while (this.#callbacks[0]) {
const handler = this.#callbacks[0];
this.#runOneCallback(handler);
this.#callbacks.shift();
}
}
//判断状态
#isPending(state) {
return state === PENDING;
}

//执行回调
#runOneCallback(callback) {
//任务放入微队列执行
isMicroQueue(() => {
const { executor, state, resolve, reject } = callback;
//只处理对应的状态 resolve ->执行then里的第一个参数 reject ->执行then里的第二个参数
if (this.#state !== state) return;
//处理then传递参数不是函数的情况
if (typeof executor !== "function") {
this.#state === FULFILLED ? resolve(this.#value) : reject(this.#value);
return;
}
try {
const result = executor(this.#value);
//保证then返回的promise状态与返回的promise一致
if (isPromise(result)) {
result.then(resolve, reject);
} else {
resolve(result);
}
} catch (error) {
reject(error);
}
});
}
then(onFulfilled, onRejected) {
return new MyPromise((resolve, reject) => {
//收集对应状态的回调
this.#pushCallback(onFulfilled, FULFILLED, resolve, reject);
this.#pushCallback(onRejected, REJECTED, resolve, reject);
this.#runCallbacks();
});
}
//catch方法就是then方法第二个参数的简写
catch(onRejected) {
return this.then(undefined, onRejected);
}
//finally方法 无论什么状态都会执行
finally(onFinally) {
this.then(
(val) => {
onFinally();
return val;
},
(err) => {
onFinally();
throw err;
}
);
}
//静态方法
static resolve(value) {
if (value instanceof MyPromise) return value;
return new MyPromise((resolve, reject) => {
if (isPromise(value)) {
value.then(resolve, reject);
} else {
resolve(value);
}
});
}
static reject(value) {
return new MyPromise((resolve, reject) => {
reject(value);
});
}
static all(promises) {
return new MyPromise((resolve, reject) => {
try {
//收集结果
const result = [];
let count = 0;
let fulfilledCount = 0;
for (const item of promises) {
//保证all返回结果的顺序
let i = count;
count++;
MyPromise.resolve(item).then((res) => {
result[i] = res;
fulfilledCount++;
if (fulfilledCount === count) {
resolve(result);
}
}, reject);
}
//如果传入空数组直接返回成功
if (count === 0) {
resolve(result);
}
} catch (error) {
reject(error);
}
});
}
}