返回

从零实现 Promise:揭秘异步编程的秘密武器

前端

引言:异步编程的挑战

在现代 Web 开发中,异步编程已成为不可或缺的一部分。它允许我们在等待服务器响应或其他耗时操作时继续执行代码,从而提高应用程序的响应能力。然而,异步编程也带来了独特的挑战,例如处理回调函数的复杂性和难以调试的代码。

Promise 的诞生:解决异步编程的救星

为了解决这些挑战,JavaScript 引入了 Promise,它提供了一种优雅且可管理的方式来处理异步操作。Promise 本质上是一个对象,它表示一个异步操作的最终完成或失败。

构建一个简易版的 Promise

为了更深入地理解 Promise 的工作原理,让我们从头开始构建一个简易版的 Promise。

1. 初始化 Promise

function MyPromise(executor) {
  this.state = 'pending';
  this.value = undefined;
  this.reason = undefined;
  this.thenCallbacks = [];
  this.catchCallbacks = [];

  executor(resolve.bind(this), reject.bind(this));
}

2. 解析 Promise

function resolve(value) {
  if (this.state !== 'pending') return;

  this.state = 'fulfilled';
  this.value = value;

  setTimeout(() => {
    this.thenCallbacks.forEach(callback => callback(value));
  }, 0);
}

3. 拒绝 Promise

function reject(reason) {
  if (this.state !== 'pending') return;

  this.state = 'rejected';
  this.reason = reason;

  setTimeout(() => {
    this.catchCallbacks.forEach(callback => callback(reason));
  }, 0);
}

4. 添加 then 方法

MyPromise.prototype.then = function(onFulfilled, onRejected) {
  if (this.state === 'fulfilled') {
    onFulfilled(this.value);
  } else if (this.state === 'rejected') {
    onRejected(this.reason);
  } else {
    this.thenCallbacks.push(onFulfilled);
    this.catchCallbacks.push(onRejected);
  }

  return new MyPromise((resolve, reject) => {
    setTimeout(() => {
      try {
        const result = onFulfilled(this.value);
        resolve(result);
      } catch (error) {
        reject(error);
      }
    }, 0);
  });
};

5. 添加 catch 方法

MyPromise.prototype.catch = function(onRejected) {
  return this.then(null, onRejected);
};

使用我们的简易版 Promise

现在,我们已经创建了简易版 Promise,我们可以像这样使用它:

const myPromise = new MyPromise((resolve, reject) => {
  setTimeout(() => {
    resolve('异步操作成功完成');
  }, 2000);
});

myPromise
  .then(result => {
    console.log(result); // 输出:'异步操作成功完成'
  })
  .catch(error => {
    console.error(error); // 不会执行
  });

结论:掌握异步编程的利器

通过从零开始构建简易版 Promise,我们深入了解了异步编程的原理。Promise 提供了一种优雅且可管理的方式来处理异步操作,它让我们的代码更具可读性和可维护性。熟练掌握 Promise 是成为一名合格 JavaScript 开发者的必备技能。