返回
一切从简,实现Promise,链式调用你就能飞
前端
2024-01-10 16:00:12
在面试的时候,经常会有面试官让你实现一个 Promise。如果按照 Promise A+ 规范来实现的话,你可能面到天黑都结束不了。
这篇文章将带你用 20 行代码实现一个最简版的 Promise。虽然它没有那么强大,但足以应付大部分情况下的异步需求,并且能够支持链式调用。让我们一步一步来实现它吧!
首先,我们先来定义一个 Promise 类,代码如下:
class Promise {
constructor(executor) {
this.state = 'pending'; // 存储 Promise 的状态
this.value = undefined; // 存储 Promise 的最终值
this.reason = undefined; // 存储 Promise 的拒绝原因
this.onFulfilledCallbacks = []; // 存储 Promise 的成功回调函数
this.onRejectedCallbacks = []; // 存储 Promise 的失败回调函数
try {
executor(this.resolve.bind(this), this.reject.bind(this)); // 立即执行执行器函数
} catch (error) {
this.reject(error); // 如果执行器函数执行失败,则将 Promise 的状态设置为拒绝
}
}
resolve(value) {
if (this.state !== 'pending') return; // 如果 Promise 的状态不是 pending,则忽略
this.state = 'fulfilled'; // 将 Promise 的状态设置为 fulfilled
this.value = value; // 将 Promise 的最终值设置为 value
this.onFulfilledCallbacks.forEach(fn => fn(value)); // 依次执行所有成功的回调函数
}
reject(reason) {
if (this.state !== 'pending') return; // 如果 Promise 的状态不是 pending,则忽略
this.state = 'rejected'; // 将 Promise 的状态设置为 rejected
this.reason = reason; // 将 Promise 的拒绝原因设置为 reason
this.onRejectedCallbacks.forEach(fn => fn(reason)); // 依次执行所有失败的回调函数
}
then(onFulfilled, onRejected) {
return new Promise((resolve, reject) => {
if (this.state === 'pending') {
this.onFulfilledCallbacks.push(() => { // 将成功的回调函数推入回调函数数组
try {
const value = onFulfilled(this.value); // 执行成功的回调函数
resolve(value); // 将成功回调函数的返回值作为下个 Promise 的成功值
} catch (error) {
reject(error); // 如果成功回调函数执行失败,则将 Promise 的状态设置为拒绝
}
});
this.onRejectedCallbacks.push(() => { // 将失败的回调函数推入回调函数数组
try {
const reason = onRejected(this.reason); // 执行失败的回调函数
reject(reason); // 将失败回调函数的返回值作为下个 Promise 的拒绝原因
} catch (error) {
reject(error); // 如果失败回调函数执行失败,则将 Promise 的状态设置为拒绝
}
});
} else if (this.state === 'fulfilled') {
try {
const value = onFulfilled(this.value); // 执行成功的回调函数
resolve(value); // 将成功回调函数的返回值作为下个 Promise 的成功值
} catch (error) {
reject(error); // 如果成功回调函数执行失败,则将 Promise 的状态设置为拒绝
}
} else if (this.state === 'rejected') {
try {
const reason = onRejected(this.reason); // 执行失败的回调函数
reject(reason); // 将失败回调函数的返回值作为下个 Promise 的拒绝原因
} catch (error) {
reject(error); // 如果失败回调函数执行失败,则将 Promise 的状态设置为拒绝
}
}
});
}
}
现在,我们已经完成了最简 Promise 类的实现。接下来,让我们通过一个简单的例子来演示它的用法:
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Hello, Promise!'); // 1 秒后将 Promise 的状态设置为成功,并传递一个值
}, 1000);
});
promise.then((value) => {
console.log(value); // 输出 "Hello, Promise!"
});
在上面的代码中,我们首先创建了一个 Promise 对象,并在执行器函数中使用 setTimeout 模拟一个异步操作。1 秒后,我们将 Promise 的状态设置为成功,并传递一个值 "Hello, Promise!"。然后,我们调用 Promise 的 then 方法,并传递了一个成功的回调函数。当 Promise 的状态变成成功时,这个回调函数将被调用,并输出 "Hello, Promise!"。
这就是最简 Promise 的实现和用法。虽然它没有那么强大,但足以应付大部分情况下的异步需求,并且能够支持链式调用。希望这篇文章对你有帮助,如果你有任何问题,请随时留言。