一个易懂的 Promise/A+ 实现:自己动手尝试!
2024-02-20 16:08:59
自己手撸一个符合Promise/A+的Promise
Promise是什么,相信不用说了,写过js的人或多或少都接触过。刚开始用Promise的时候,总感觉这种写法非常的怪异,但是当慢慢熟悉的时候,发现一切都是那么和谐。 我自己理解的Promise用来解决异步回调嵌套的问题,它代表了异步操作的一种结果。它是一种状态机,从实现上来说,它的状态只有pending、fulfilled、rejected三种,pending表示进行中,fulfilled表示成功,rejected表示失败。
现在我们来自己动手实现一个Promise,使用原生JavaScript即可。
class Promise {
constructor(executor) {
this.state = 'pending'; // 初始状态为pending
this.value = undefined; // 成功的值
this.reason = undefined; // 失败的原因
this.onFulfilledCallbacks = []; // 成功的回调函数队列
this.onRejectedCallbacks = []; // 失败的回调函数队列
const resolve = (value) => {
if (this.state === 'pending') {
this.state = 'fulfilled';
this.value = value;
this.onFulfilledCallbacks.forEach((callback) => {
callback(value);
});
}
};
const reject = (reason) => {
if (this.state === 'pending') {
this.state = 'rejected';
this.reason = reason;
this.onRejectedCallbacks.forEach((callback) => {
callback(reason);
});
}
};
executor(resolve, reject);
}
then(onFulfilled, onRejected) {
return new Promise((resolve, reject) => {
if (this.state === 'fulfilled') {
onFulfilled(this.value);
resolve(this.value);
} else if (this.state === 'rejected') {
onRejected(this.reason);
reject(this.reason);
} else {
this.onFulfilledCallbacks.push(() => {
onFulfilled(this.value);
resolve(this.value);
});
this.onRejectedCallbacks.push(() => {
onRejected(this.reason);
reject(this.reason);
});
}
});
}
}
这是一个基本的Promise实现,包含了三个状态(pending、fulfilled、rejected)和两个回调函数队列(onFulfilledCallbacks、onRejectedCallbacks)。我们通过executor函数来执行异步操作,并将成功或失败的结果通过resolve和reject函数传递给Promise对象。然后,我们可以在then方法中添加成功的回调函数和失败的回调函数,以便在Promise的状态改变时执行相应的操作。
需要注意的是,我们的Promise实现并不完全符合Promise/A+规范,但它可以满足大多数场景的需求。如果您需要一个完全符合Promise/A+规范的Promise实现,可以参考一些第三方库,如bluebird、q等。
如何使用Promise
使用Promise非常简单,只需以下几个步骤:
- 实例化一个Promise对象:
const promise = new Promise((resolve, reject) => {
// 异步操作
});
- 在Promise对象上调用then方法,添加成功的回调函数和失败的回调函数:
promise.then((value) => {
// 成功时执行
}, (reason) => {
// 失败时执行
});
- 在then方法中,可以返回另一个Promise对象,以便继续链式调用:
promise.then((value) => {
return new Promise((resolve, reject) => {
// 继续异步操作
});
}).then((value) => {
// 继续执行
});
Promise的优点
Promise相比于传统的回调函数,具有以下优点:
- 提高代码可读性和可维护性:Promise将异步操作包装成一个对象,使代码更加结构化和易于理解。
- 支持链式调用:Promise支持链式调用,可以将多个异步操作串联起来,使代码更加简洁。
- 错误处理更方便:Promise可以捕获错误并传递给下一个then方法,使错误处理更加方便。
总结
Promise是一种非常有用的工具,可以帮助我们解决异步编程中的许多问题。通过自己动手实现一个Promise,我们可以更好地理解Promise的原理和用法。