ES6 Promise 的实现只有 72 行?谁还能更少?
2023-10-27 14:43:05
当我们谈论 JavaScript 的异步编程时,Promise
对象是绕不开的话题。Promise
对象提供了一种简单而有效的方式来处理异步操作,它允许我们将异步操作的结果传递给后续的回调函数。
ES6 规范中内置了 Promise
对象,它的实现只有短短 72 行代码,这让人不禁惊叹于 JavaScript 的强大和简洁。但是,对于那些喜欢挑战极限的人来说,他们可能会问:谁还能更少?
ES6 Promise 的实现
ES6 Promise 的实现非常简单,它的核心代码如下:
function Promise(executor) {
this.state = 'pending';
this.value = undefined;
this.reason = undefined;
this.onFulfilledCallbacks = [];
this.onRejectedCallbacks = [];
const resolve = (value) => {
if (this.state !== 'pending') return;
this.state = 'fulfilled';
this.value = value;
this.onFulfilledCallbacks.forEach((callback) => {
callback(value);
});
};
const reject = (reason) => {
if (this.state !== 'pending') return;
this.state = 'rejected';
this.reason = reason;
this.onRejectedCallbacks.forEach((callback) => {
callback(reason);
});
};
try {
executor(resolve, reject);
} catch (error) {
reject(error);
}
}
在这个实现中,Promise
对象包含四个属性:
state
:表示Promise
对象的状态,可以是pending
(等待)、fulfilled
(已完成)或rejected
(已拒绝)。value
:如果Promise
对象的状态是fulfilled
,则value
属性包含Promise
对象完成时的值。reason
:如果Promise
对象的状态是rejected
,则reason
属性包含Promise
对象被拒绝时的原因。onFulfilledCallbacks
和onRejectedCallbacks
:这两个属性是回调函数的数组,分别用于在Promise
对象完成或被拒绝时调用。
Promise
对象的构造函数接受一个 executor
函数作为参数,executor
函数有两个参数:resolve
和 reject
。resolve
函数用于将 Promise
对象的状态设置为 fulfilled
,reject
函数用于将 Promise
对象的状态设置为 rejected
。
Promise
对象还提供了 then()
方法,用于将 Promise
对象连接起来。then()
方法接受两个回调函数作为参数:onFulfilled
和 onRejected
。当 Promise
对象的状态变为 fulfilled
时,onFulfilled
回调函数将被调用,并将 Promise
对象完成时的值作为参数。当 Promise
对象的状态变为 rejected
时,onRejected
回调函数将被调用,并将 Promise
对象被拒绝时的原因作为参数。
优化代码行数
ES6 Promise 的实现已经非常简洁了,但我们还是可以进一步优化代码行数。例如,我们可以使用箭头函数来替代普通函数,还可以使用解构赋值来简化代码。优化后的代码如下:
const Promise = (executor) => {
let state = 'pending';
let value, reason;
const onFulfilledCallbacks = [];
const onRejectedCallbacks = [];
const resolve = (value) => {
if (state !== 'pending') return;
state = 'fulfilled';
this.value = value;
onFulfilledCallbacks.forEach((callback) => callback(value));
};
const reject = (reason) => {
if (state !== 'pending') return;
state = 'rejected';
this.reason = reason;
onRejectedCallbacks.forEach((callback) => callback(reason));
};
try {
executor(resolve, reject);
} catch (error) {
reject(error);
}
};
经过优化后,ES6 Promise 的实现只剩下 45 行代码。
使用 ES6 Promise
ES6 Promise 的使用非常简单,我们只需要创建一个 Promise
对象,然后在 Promise
对象上调用 then()
方法即可。例如:
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Hello, world!');
}, 1000);
});
promise.then((value) => {
console.log(value); // 输出: Hello, world!
});
在上面的代码中,我们创建了一个 Promise
对象,并在 1 秒后将 Promise
对象的状态设置为 fulfilled
,并将 "Hello, world!"
作为 Promise
对象完成时的值。然后,我们在 Promise
对象上调用 then()
方法,并指定了一个回调函数。当 Promise
对象的状态变为 fulfilled
时,这个回调函数将被调用,并将 Promise
对象完成时的值作为参数。
总结
ES6 Promise 是一个非常强大的工具,它使我们能够轻松地处理异步操作。ES6 Promise 的实现也非常简洁,只有短短 45 行代码。如果您想了解更多关于 ES6 Promise 的信息,可以参考 MDN 文档。