返回
手写Promise:揭秘实现机制与过程,深入理解Promise核心要点
前端
2023-10-01 03:39:14
了解 Promise 核心代码,是掌握异步编程的关键一步。Promise,作为处理异步操作的强有力工具,能帮助我们轻松处理回调函数,使代码更加整洁易读。下面,我们就来手把手地编写 Promise 核心代码,并深入理解 Promise 的实现机制与过程。
一、Promise 的设计思路
首先,我们来了解 Promise 的设计思路。Promise 本质上是一个对象,它拥有三种状态:Pending、Fulfilled 和 Rejected。Pending 表示 Promise 处于等待状态,Fulfilled 表示 Promise 已完成并成功执行,Rejected 表示 Promise 已完成但执行失败。
二、Promise 核心代码实现
接下来,我们就来实现 Promise 的核心代码。
class Promise {
constructor(executor) {
this.state = "pending"; // 初始状态为 Pending
this.value = undefined; // 存储执行成功后的值
this.reason = undefined; // 存储执行失败后的原因
this.onFulfilledCallbacks = []; // 存储成功的回调函数
this.onRejectedCallbacks = []; // 存储失败的回调函数
// 立即执行 executor,将 resolve 和 reject 传递进去
try {
executor(this.resolve, this.reject);
} catch (error) {
this.reject(error); // executor 执行时出错,直接进入 Rejected 状态
}
}
resolve(value) {
// 检查状态是否为 Pending
if (this.state !== "pending") {
return;
}
// 将状态从 Pending 转换为 Fulfilled
this.state = "fulfilled";
// 将成功的结果保存起来
this.value = value;
// 执行所有成功的回调函数
this.onFulfilledCallbacks.forEach((callback) => callback(value));
}
reject(reason) {
// 检查状态是否为 Pending
if (this.state !== "pending") {
return;
}
// 将状态从 Pending 转换为 Rejected
this.state = "rejected";
// 将失败的原因保存起来
this.reason = reason;
// 执行所有失败的回调函数
this.onRejectedCallbacks.forEach((callback) => callback(reason));
}
then(onFulfilled, onRejected) {
// 处理 onFulfilled 为非函数的情况
onFulfilled = typeof onFulfilled === "function" ? onFulfilled : (value) => value;
// 处理 onRejected 为非函数的情况
onRejected = typeof onRejected === "function" ? onRejected : (reason) => { throw reason; };
const promise2 = new Promise((resolve, reject) => {
// 如果状态为 Fulfilled,执行 onFulfilled 并将结果传递给下一个 Promise
if (this.state === "fulfilled") {
setTimeout(() => {
try {
const x = onFulfilled(this.value);
resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
}
}, 0);
}
// 如果状态为 Rejected,执行 onRejected 并将原因传递给下一个 Promise
if (this.state === "rejected") {
setTimeout(() => {
try {
const x = onRejected(this.reason);
resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
}
}, 0);
}
// 如果状态为 Pending,将回调函数保存起来,等待状态改变后再执行
if (this.state === "pending") {
this.onFulfilledCallbacks.push(() => {
setTimeout(() => {
try {
const x = onFulfilled(this.value);
resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
}
}, 0);
});
this.onRejectedCallbacks.push(() => {
setTimeout(() => {
try {
const x = onRejected(this.reason);
resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
}
}, 0);
});
}
});
return promise2;
}
}
// 处理 then 返回值的 Promise 的情况
function resolvePromise(promise2, x, resolve, reject) {
if (promise2 === x) {
reject(new TypeError("循环引用"));
}
if (x instanceof Promise) {
x.then((y) => {
resolvePromise(promise2, y, resolve, reject);
}, reject);
} else if (x !== null && (typeof x === "object" || typeof x === "function")) {
try {
const then = x.then;
if (typeof then === "function") {
then.call(
x,
(y) => {
resolvePromise(promise2, y, resolve, reject);
},
(r) => {
reject(r);
}
);
} else {
resolve(x);
}
} catch (error) {
reject(error);
}
} else {
resolve(x);
}
}
三、Promise 的使用
现在,我们已经了解了 Promise 的核心代码,接下来就让我们看看如何使用 Promise。
// 创建一个 Promise
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("Hello, World!"); // 将结果传递给 resolve 函数
}, 2000);
});
// 使用 then 方法处理 Promise 的结果
promise.then((result) => {
console.log(result); // 输出 "Hello, World!"
}, (reason) => {
console.log(reason); // 如果 Promise 失败,则输出失败的原因
});
结语
通过手写 Promise 的核心代码,我们深入理解了 Promise 的内部机制和工作原理。这不仅有助于我们更好地掌握异步编程,也能让我们更加灵活地使用 Promise,轻松处理复杂的异步操作。希望这篇文章对您有所帮助,也欢迎您继续探索 Promise 的更多用法。