class MyPromise {
constructor(executor) {
// 初始状态为 pending
this.status = "pending";
// 存储 resolve 和 reject 的结果
this.value = undefined;
this.error = undefined;
// 存储成功回调和失败回调
this.onResolvedCallbacks = [];
this.onRejectedCallbacks = [];
// 执行执行器函数,传入 resolve 和 reject 函数
try {
executor(this.resolve.bind(this), this.reject.bind(this));
} catch (e) {
this.reject(e);
}
}
// resolve 方法将 Promise 状态改为 fulfilled,存储 resolve 后的值,并执行成功回调
resolve(value) {
if (this.status === "pending") {
this.status = "fulfilled";
this.value = value;
this.onResolvedCallbacks.forEach((fn) => fn());
}
}
// reject 方法将 Promise 状态改为 rejected,存储 reject 后的值,并执行失败回调
reject(error) {
if (this.status === "pending") {
this.status = "rejected";
this.error = error;
this.onRejectedCallbacks.forEach((fn) => fn());
}
}
// then 方法接收两个参数,成功回调和失败回调
then(onResolved, onRejected) {
// 创建一个新的 Promise 对象
const promise2 = new MyPromise((resolve, reject) => {
// 如果当前状态是 fulfilled,则执行成功回调,并将其返回值传递给下一个 Promise
if (this.status === "fulfilled") {
setTimeout(() => {
try {
const x = onResolved(this.value);
this.resolvePromise(promise2, x, resolve, reject); // 解析链式 Promise
} catch (e) {
reject(e);
}
}, 0);
}
// 如果当前状态是 rejected,则执行失败回调,并将其返回值传递给下一个 Promise
if (this.status === "rejected") {
setTimeout(() => {
try {
const x = onRejected(this.error);
this.resolvePromise(promise2, x, resolve, reject); // 解析链式 Promise
} catch (e) {
reject(e);
}
}, 0);
}
// 如果当前状态是 pending,则分别将成功回调和失败回调存储到数组中,等待状态改变后执行
if (this.status === "pending") {
this.onResolvedCallbacks.push(() => {
setTimeout(() => {
try {
const x = onResolved(this.value);
this.resolvePromise(promise2, x, resolve, reject); // 解析链式 Promise
} catch (e) {
reject(e);
}
}, 0);
});
this.onRejectedCallbacks.push(() => {
setTimeout(() => {
try {
const x = onRejected(this.error);
this.resolvePromise(promise2, x, resolve, reject); // 解析链式 Promise
} catch (e) {
reject(e);
}
}, 0);
});
}
});
return promise2;
}
// 解析链式 Promise
resolvePromise(promise2, x, resolve, reject) {
// 如果 promise2 和 x 相等,则抛出 TypeError
if (promise2 === x) {
return reject(new TypeError("Chaining cycle detected for promise!"));
}
// 如果 x 是一个 Promise,则等待它的状态改变后再处理
if (x instanceof MyPromise) {
x.then(
(value) => this.resolvePromise(promise2, value, resolve, reject),
(error) => reject(error)
);
} else {
// 如果 x 是一个普通值,则直接传递给下一个 Promise
resolve(x);
}
}
// catch 方法用来捕获 Promise 的错误
catch(onRejected) {
return this.then(null, onRejected);
}
// finally 方法用来在 Promise 执行结束后执行一些操作
finally(callback) {
return this.then(
(value) => MyPromise.resolve(callback()).then(() => value),
(error) =>
MyPromise.resolve(callback()).then(() => {
throw error;
})
);
}
// all 方法用来将多个 Promise 实例包装成一个新的 Promise 实例
static all(promises) {
return new MyPromise((resolve, reject) => {
const results = [];
let count = 0;
for (let i = 0; i < promises.length; i++) {
// 如果 promises[i] 不是一个 Promise,则将其视为已经 fulfilled 状态的 Promise
if (!(promises[i] instanceof MyPromise)) {
promises[i] = MyPromise.resolve(promises[i]);
}
// 监听每个 Promise 的状态变化,如果全部都变成 fulfilled,则将结果数组传递给下一个 Promise
promises[i].then(
(value) => {
results[i] = value;
count++;
if (count === promises.length) {
resolve(results);
}
},
(error) => {
reject(error);
}
);
}
});
}
// race 方法返回一个新的 Promise,它将由第一个完成的 Promise 的值或错误来决定自己的状态和值
static race(promises) {
return new MyPromise((resolve, reject) => {
for (let i = 0; i < promises.length; i++) {
// 如果 promises[i] 不是一个 Promise,则将其视为已经 fulfilled 状态的 Promise
if (!(promises[i] instanceof MyPromise)) {
promises[i] = MyPromise.resolve(promises[i]);
}
// 监听每个 Promise 的状态变化,如果有一个变成 fulfilled 或 rejected,则将其状态和值传递给下一个 Promise
promises[i].then(
(value) => {
resolve(value);
},
(error) => {
reject(error);
}
);
}
});
}
// resolve 方法返回一个新的 Promise,它的状态和值都是已知的
static resolve(value) {
return new MyPromise((resolve, reject) => {
resolve(value);
});
}
// reject 方法返回一个新的 Promise,它的状态和错误都是已知的
static reject(error) {
return new MyPromise((resolve, reject) => {
reject(error);
});
}
}
// 测试代码
const p1 = new MyPromise((resolve, reject) => {
setTimeout(() => {
resolve("p1");
}, 1000);
});
const p2 = new MyPromise((resolve, reject) => {
setTimeout(() => {
reject("p2");
}, 500);
});
MyPromise.all([p1, p2])
.then((results) => {
console.log(results); // ["p1", undefined]
})
.catch((error) => {
console.log(error); // "p2"
});
MyPromise.race([p1, p2])
.then((result) => {
console.log(result); // "p1"
})
.catch((error) => {
console.log(error); // "p2"
});
手写Promise
最新推荐文章于 2024-10-02 05:39:15 发布