返回
Promise 的手写实现
前端
2024-01-28 09:48:45
前言
Promise 是一种用于处理异步编程的 JavaScript 对象,它允许我们以更优雅和可读的方式处理异步操作的结果。虽然 Promise 在现代 JavaScript 中无处不在,但理解其底层的工作原理可以帮助我们更有效地使用它。
状态的定义
Promise 的核心是一个内部状态,它可以是以下三种之一:
- Pending(待定): Promise 尚未完成或失败。
- Fulfilled(已完成): Promise 已成功完成,并带有结果值。
- Rejected(已拒绝): Promise 已失败,并带有错误原因。
改变状态的方法
Promise 提供了两个改变其状态的方法:
- resolve(): 将 Promise 标记为已完成,并设置其结果值。
- reject(): 将 Promise 标记为已拒绝,并设置其错误原因。
then 方法
then() 方法允许我们为 Promise 指定回调函数,这些回调函数将在 Promise 改变状态时执行。then() 方法有两个参数:
- onFulfilled(): 在 Promise 已完成时调用的回调函数。
- onRejected(): 在 Promise 已拒绝时调用的回调函数。
resolvePromise 解析
resolvePromise() 是一个辅助函数,用于解析 Promise 的值。当 then() 回调函数返回一个 Promise 时,resolvePromise() 会自动解析该 Promise 并将结果传递给下一个 then() 回调函数。
手写实现
现在,让我们一步步手写实现 Promise:
function Promise(executor) {
// 内部状态
this.state = 'pending';
// 结果值
this.value = undefined;
// 错误原因
this.reason = undefined;
// 存储 then 回调函数
this.onFulfilledCallbacks = [];
this.onRejectedCallbacks = [];
// 改变状态的方法
const resolve = (value) => {
if (this.state !== 'pending') return;
this.state = 'fulfilled';
this.value = value;
// 执行 then 回调函数
this.onFulfilledCallbacks.forEach(callback => callback(value));
};
const reject = (reason) => {
if (this.state !== 'pending') return;
this.state = 'rejected';
this.reason = reason;
// 执行 then 回调函数
this.onRejectedCallbacks.forEach(callback => callback(reason));
};
// then 方法
this.then = (onFulfilled, onRejected) => {
return new Promise((resolve, reject) => {
// 处理 onFulfilled 回调函数
if (onFulfilled) {
this.onFulfilledCallbacks.push(() => {
try {
// 捕获任何错误
const result = onFulfilled(this.value);
// 解析结果 Promise
resolvePromise(result, resolve, reject);
} catch (error) {
reject(error);
}
});
}
// 处理 onRejected 回调函数
if (onRejected) {
this.onRejectedCallbacks.push(() => {
try {
// 捕获任何错误
const result = onRejected(this.reason);
// 解析结果 Promise
resolvePromise(result, resolve, reject);
} catch (error) {
reject(error);
}
});
}
});
};
// 执行 executor 函数
executor(resolve, reject);
}
示例用法
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('成功!');
}, 1000);
});
promise.then((result) => {
console.log('成功结果:', result);
}).catch((reason) => {
console.error('失败原因:', reason);
});
总结
我们已经从零开始手写实现了 Promise。通过理解其状态管理、改变状态的方法、then() 方法和 resolvePromise() 解析,我们现在可以更好地理解 Promise 在异步编程中的强大作用。手写实现是一个很好的练习,可以帮助我们深入了解 Promise 的内部运作原理。