返回
Promise 的实践指南:从头开始实现它的全部功能
前端
2023-10-01 06:59:27
了解 Promise 的奥秘:亲自动手实现它的强大功能
引言
Promise 是 JavaScript 中异步编程的基石,它简化了异步操作的处理,让开发者可以轻松处理复杂的异步逻辑。虽然有许多库和框架提供了开箱即用的 Promise 实现,但亲自动手实现 Promise 对于深入理解其工作原理和掌握异步编程至关重要。本文将带领您一步一步地实现 Promise 的所有方法,揭示其背后的魔力。
什么是 Promise?
Promise 是一个表示异步操作的最终结果的对象。它可以处于三种状态:
- Pending: 操作正在进行中。
- Fulfilled: 操作已成功完成。
- Rejected: 操作已失败。
实现 Promise
实现 Promise 涉及创建和管理三个核心方法:
- constructor :创建一个新的 Promise 对象。
- then :添加回调函数以处理 Promise 的结果。
- catch :添加回调函数以处理 Promise 的拒绝。
constructor
constructor
方法使用以下语法创建新的 Promise 对象:
const promise = new Promise((resolve, reject) => {});
resolve
函数用于将 Promise 标记为已完成并提供结果值。reject
函数用于将 Promise 标记为已拒绝并提供错误值。
then
then
方法用于添加回调函数来处理 Promise 的结果:
promise.then((result) => {
// 成功回调:处理已完成的 Promise。
});
- 成功回调函数接收 Promise 的结果作为参数。
catch
catch
方法用于添加回调函数来处理 Promise 的拒绝:
promise.catch((error) => {
// 拒绝回调:处理已拒绝的 Promise。
});
- 拒绝回调函数接收 Promise 的错误值作为参数。
Promise 链
Promise 可以链接在一起形成链,以便轻松处理多个异步操作的顺序执行:
promise1
.then((result1) => promise2(result1))
.then((result2) => promise3(result2))
.catch((error) => {
// 处理任何 Promise 拒绝。
});
实践示例
考虑一个示例,其中我们将实现一个 Promise,该 Promise 以异步方式获取用户的年龄:
const getAge = (userId) => {
return new Promise((resolve, reject) => {
// 模拟异步操作。
setTimeout(() => {
const age = Math.floor(Math.random() * 100);
resolve(age);
}, 1000);
});
};
使用示例
getAge(1)
.then((age) => {
console.log(`用户年龄:${age}`);
})
.catch((error) => {
console.log(`错误:${error}`);
});
完整实现
以下是最完整的 Promise 实现:
class Promise {
constructor(executor) {
this.state = "pending";
this.result = undefined;
this.error = undefined;
this.successCallbacks = [];
this.failureCallbacks = [];
const resolve = (result) => {
if (this.state !== "pending") return;
this.state = "fulfilled";
this.result = result;
this.successCallbacks.forEach((callback) => callback(result));
};
const reject = (error) => {
if (this.state !== "pending") return;
this.state = "rejected";
this.error = error;
this.failureCallbacks.forEach((callback) => callback(error));
};
executor(resolve, reject);
}
then(successCallback, failureCallback) {
if (this.state === "fulfilled") {
successCallback(this.result);
} else if (this.state === "rejected") {
failureCallback(this.error);
} else {
this.successCallbacks.push(successCallback);
this.failureCallbacks.push(failureCallback);
}
}
catch(failureCallback) {
this.then(null, failureCallback);
}
}