返回
从零构建 Promise,逐一剖析then、all、race、resolve、reject、finally等核心方法
前端
2023-11-17 16:27:22
Promise 的基本原理
Promise 是一个对象,它表示一个异步操作的最终完成或失败的状态。当一个 Promise 被创建时,它会立即处于 pending 状态。当异步操作完成时,Promise 会被解析(resolved)或拒绝(rejected)。一旦 Promise 被解析或拒绝,它的状态就无法再改变。
Promise 的核心方法
Promise 提供了几个核心方法,用于处理异步操作和获取异步操作的结果。这些方法包括:
then()
:then() 方法用于在 Promise 被解析或拒绝时执行相应的回调函数。all()
:all() 方法用于等待多个 Promise 都被解析,然后执行回调函数。race()
:race() 方法用于等待多个 Promise 中的第一个被解析或拒绝,然后执行回调函数。resolve()
:resolve() 方法用于将 Promise 的状态解析为已完成。reject()
:reject() 方法用于将 Promise 的状态拒绝为已失败。finally()
:finally() 方法用于在 Promise 被解析或拒绝后执行回调函数。
手写 Promise
现在,让我们从零构建一个基础版的 Promise。
class Promise {
constructor(executor) {
this.state = "pending"; // Promise 的初始状态
this.value = undefined; // Promise 的值
this.reason = undefined; // Promise 的原因
this.onFulfilledCallbacks = []; // Promise 被解析时要执行的回调函数队列
this.onRejectedCallbacks = []; // Promise 被拒绝时要执行的回调函数队列
// 执行器函数,用于执行异步操作并解析或拒绝 Promise
try {
executor(
// resolve() 函数,用于将 Promise 的状态解析为已完成
(value) => {
this.resolve(value);
},
// reject() 函数,用于将 Promise 的状态拒绝为已失败
(reason) => {
this.reject(reason);
}
);
} catch (error) {
// 如果执行器函数抛出错误,则将 Promise 的状态拒绝为已失败
this.reject(error);
}
}
// 将 Promise 的状态解析为已完成
resolve(value) {
if (this.state !== "pending") {
return;
}
this.state = "fulfilled";
this.value = value;
// 执行所有已注册的 onFulfilled 回调函数
this.onFulfilledCallbacks.forEach((callback) => {
callback(value);
});
}
// 将 Promise 的状态拒绝为已失败
reject(reason) {
if (this.state !== "pending") {
return;
}
this.state = "rejected";
this.reason = reason;
// 执行所有已注册的 onRejected 回调函数
this.onRejectedCallbacks.forEach((callback) => {
callback(reason);
});
}
// then() 方法
then(onFulfilled, onRejected) {
// 返回一个新的 Promise
return new Promise((resolve, reject) => {
// 如果 Promise 已经解析,则立即执行 onFulfilled 回调函数
if (this.state === "fulfilled") {
setTimeout(() => {
try {
const value = onFulfilled(this.value);
resolve(value);
} catch (error) {
reject(error);
}
}, 0);
return;
}
// 如果 Promise 已经拒绝,则立即执行 onRejected 回调函数
if (this.state === "rejected") {
setTimeout(() => {
try {
const reason = onRejected(this.reason);
reject(reason);
} catch (error) {
reject(error);
}
}, 0);
return;
}
// 如果 Promise 仍然处于 pending 状态,则将 onFulfilled 和 onRejected 回调函数添加到队列中
this.onFulfilledCallbacks.push((value) => {
setTimeout(() => {
try {
const value = onFulfilled(value);
resolve(value);
} catch (error) {
reject(error);
}
}, 0);
});
this.onRejectedCallbacks.push((reason) => {
setTimeout(() => {
try {
const reason = onRejected(reason);
reject(reason);
} catch (error) {
reject(error);
}
}, 0);
});
});
}
// all() 方法
static all(promises) {
return new Promise((resolve, reject) => {
// 计数器,用于跟踪已解析的 Promise 的数量
let count = 0;
// 已解析的 Promise 的值
const values = [];
// 遍历所有 Promise
promises.forEach((promise, index) => {
// then() 方法,用于处理 Promise 的解析或拒绝
promise.then(
(value) => {
// 将已解析的 Promise 的值添加到 values 数组中
values[index] = value;
// 计数器加 1
count++;
// 如果所有 Promise 都已解析,则将 values 数组作为参数解析当前 Promise
if (count === promises.length) {
resolve(values);
}
},
(reason) => {
// 如果其中一个 Promise 被拒绝,则立即拒绝当前 Promise
reject(reason);
}
);
});
});
}
// race() 方法
static race(promises) {
return new Promise((resolve, reject) => {
// 遍历所有 Promise
promises.forEach((promise) => {
// then() 方法,用于处理 Promise 的解析或拒绝
promise.then(
(value) => {
// 如果当前 Promise 尚未被解析或拒绝,则立即解析当前 Promise
if (this.state === "pending") {
resolve(value);
}
},
(reason) => {
// 如果当前 Promise 尚未被解析或拒绝,则立即拒绝当前 Promise
if (this.state === "pending") {
reject(reason);
}
}
);
});
});
}
// finally() 方法
finally(onFinally) {
// 返回一个新的 Promise
return new Promise((resolve, reject) => {
// then() 方法,用于处理当前 Promise 的解析或拒绝
this.then(
(value) => {
// 执行 onFinally 回调函数
onFinally();
// 解析新的 Promise
resolve(value);
},
(reason) => {
// 执行 onFinally 回调函数
onFinally();
// 拒绝新的 Promise
reject(reason);
}
);
});
}
}
结语
通过本文,您已经了解了 Promise 的基本原理和核心方法,并能够从零构建一个基础版的 Promise。希望这些知识能够帮助您在自己的项目中熟练使用 Promise,以实现异步编程。