返回

ES6 Promise 的实现只有 72 行?谁还能更少?

前端

当我们谈论 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 对象被拒绝时的原因。
  • onFulfilledCallbacksonRejectedCallbacks:这两个属性是回调函数的数组,分别用于在 Promise 对象完成或被拒绝时调用。

Promise 对象的构造函数接受一个 executor 函数作为参数,executor 函数有两个参数:resolverejectresolve 函数用于将 Promise 对象的状态设置为 fulfilledreject 函数用于将 Promise 对象的状态设置为 rejected

Promise 对象还提供了 then() 方法,用于将 Promise 对象连接起来。then() 方法接受两个回调函数作为参数:onFulfilledonRejected。当 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 文档。