返回

Promise 的手写实现之旅

前端

异步编程的必要性

在现代 Web 开发中,异步编程已成为必不可少的技能。随着互联网的飞速发展,人们对实时性和交互性的需求日益增长。异步编程可以使我们的代码在不阻塞主线程的情况下执行长时间或耗时的任务,从而提高应用程序的性能和响应速度。

认识 Promise

Promise 是 JavaScript 中用于处理异步操作的强大工具。它可以让我们以同步的方式编写异步代码,从而大大简化了异步编程的复杂性。

Promise 的基本概念非常简单:它是一个表示异步操作最终完成或失败的对象。我们可以通过 then() 方法来注册回调函数,当操作完成后,这些回调函数就会被调用。

Promise 的实现

现在,我们开始着手实现自己的 Promise 库。首先,我们需要定义一个 Promise 构造函数,它接受一个执行器函数作为参数。执行器函数有两个参数,分别是 resolvereject,用于分别表示操作成功和失败的情况。

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);
  }
}

接下来,我们需要实现 then() 方法。then() 方法接受两个参数,分别是 onFulfilledonRejected,用于分别处理操作成功和失败的情况。

Promise.prototype.then = function (onFulfilled, onRejected) {
  if (this.state === 'pending') {
    this.onFulfilledCallbacks.push(onFulfilled);
    this.onRejectedCallbacks.push(onRejected);
  } else if (this.state === 'fulfilled') {
    onFulfilled(this.value);
  } else if (this.state === 'rejected') {
    onRejected(this.reason);
  }

  return new Promise((resolve, reject) => {
    this.onFulfilledCallbacks.push((value) => {
      try {
        const result = onFulfilled(value);
        resolve(result);
      } catch (error) {
        reject(error);
      }
    });

    this.onRejectedCallbacks.push((reason) => {
      try {
        const result = onRejected(reason);
        resolve(result);
      } catch (error) {
        reject(error);
      }
    });
  });
};

Promise 的使用

现在,我们已经实现了自己的 Promise 库,接下来我们看看如何使用它。

首先,我们可以创建一个 Promise 对象,并通过 then() 方法注册回调函数。

const promise = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('Hello, Promise!');
  }, 2000);
});

promise.then((value) => {
  console.log(value); // 输出: Hello, Promise!
});

如果我们想在 Promise 失败时执行某些操作,我们可以使用 catch() 方法。

const promise = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject('Something went wrong!');
  }, 2000);
});

promise.catch((reason) => {
  console.log(reason); // 输出: Something went wrong!
});

结语

通过这篇教程,我们从头开始实现了自己的 Promise 库,加深了对 Promise 的理解,也更好地掌握了 JavaScript 的异步编程机制。希望这些知识能够帮助你在实际项目中编写出更加健壮和高效的异步代码。