手写Promise源码,深入理解Promise机制
2023-10-20 14:16:06
手把手实现Promise
为了更好地理解Promise的机制,我们不妨从头开始,自己实现一个Promise。
1. Promise的结构
Promise是一个类,具有构造函数和一些方法。我们首先定义Promise的构造函数,如下所示:
function Promise(executor) {
this.status = 'pending';
this.value = undefined;
this.reason = undefined;
this.onFulfilledCallbacks = [];
this.onRejectedCallbacks = [];
const resolve = (value) => {
if (this.status === 'pending') {
this.status = 'fulfilled';
this.value = value;
this.onFulfilledCallbacks.forEach(fn => fn(value));
}
};
const reject = (reason) => {
if (this.status === 'pending') {
this.status = 'rejected';
this.reason = reason;
this.onRejectedCallbacks.forEach(fn => fn(reason));
}
};
try {
executor(resolve, reject);
} catch (error) {
reject(error);
}
}
在构造函数中,我们定义了Promise的初始状态为'pending',并初始化了值(value)、原因(reason)、已完成回调(onFulfilledCallbacks)和已拒绝回调(onRejectedCallbacks)等属性。
然后,我们定义了两个函数resolve()
和reject()
,分别用于Promise的状态变为已完成和已拒绝时调用。
最后,我们在构造函数中调用executor()
函数,该函数接收两个参数:resolve()
和reject()
。executor()
函数中包含了异步操作的逻辑,当异步操作完成后,调用resolve()
或reject()
来改变Promise的状态。
2. Promise的方法
Promise提供了几个有用的方法,包括:
then()
方法:用于添加回调函数,当Promise的状态变为已完成或已拒绝时执行。catch()
方法:用于添加回调函数,当Promise的状态变为已拒绝时执行。finally()
方法:无论Promise的状态如何,都会执行的回调函数。
这些方法的使用非常简单,我们将在后面的示例中演示。
3. Promise的示例
以下是一个使用Promise的简单示例:
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('成功');
}, 1000);
});
promise.then(value => {
console.log(value); // 输出: 成功
});
在这个示例中,我们创建了一个Promise,并在构造函数中定义了一个异步操作,即延迟1秒后将值'成功'解析为Promise。
然后,我们使用then()
方法添加了一个回调函数,当Promise的状态变为已完成时执行。在回调函数中,我们打印出Promise的值'成功'。
运行这段代码,您将在控制台中看到'成功'被输出。
深入理解Promise机制
通过上面的示例,我们已经对Promise的基本用法有了一个初步的了解。下面,我们将更深入地探讨Promise的机制。
1. Promise的状态
Promise具有三个状态:
- 'pending':表示Promise尚未完成。
- 'fulfilled':表示Promise已成功完成。
- 'rejected':表示Promise已失败完成。
一个Promise只能从'pending'状态变为'fulfilled'或'rejected'状态,并且一旦状态发生变化,就不可逆转。
2. Promise的回调函数
当Promise的状态发生变化时,会执行相应的回调函数。
- 当Promise的状态变为'fulfilled'时,会执行
then()
方法中添加的回调函数。 - 当Promise的状态变为'rejected'时,会执行
catch()
方法中添加的回调函数。
这些回调函数可以接收一个参数,该参数是Promise的值(当状态为'fulfilled'时)或原因(当状态为'rejected'时)。
3. Promise的链式调用
Promise支持链式调用,即可以将多个Promise连接起来,形成一个Promise链。
promise1.then(value1 => {
return promise2(value1);
}).then(value2 => {
return promise3(value2);
}).then(value3 => {
console.log(value3);
});
在上面的示例中,我们创建了三个Promise,并将其连接成了一个Promise链。当Promise1的状态变为'fulfilled'时,会执行第一个then()
方法中的回调函数,并返回Promise2。
当Promise2的状态变为'fulfilled'时,会执行第二个then()
方法中的回调函数,并返回Promise3。
当Promise3的状态变为'fulfilled'时,会执行第三个then()
方法中的回调函数,并打印出Promise3的值。
4. Promise的异常处理
如果在Promise的构造函数中或then()
方法的回调函数中抛出异常,则Promise的状态会变为'rejected',并会执行catch()
方法中添加的回调函数。
const promise = new Promise((resolve, reject) => {
throw new Error('错误');
});
promise.catch(reason => {
console.log(reason); // 输出: 错误
});
在这个示例中,我们创建了一个Promise,并在构造函数中抛出