返回

浏览器异步运行机制揭秘:手把手教你玩转Promise(二)—— 手写Promise

前端

浏览器异步运行机制:了解Promise的基础

在探索Promise之前,我们先来了解一下浏览器的异步运行机制。浏览器在执行代码时,会将代码分为同步任务和异步任务。同步任务会按照代码顺序执行,而异步任务则会放到一个队列中等待执行。当异步任务完成后,浏览器会将其从队列中取出并执行。

Promise是JavaScript中处理异步任务的利器。它可以让你在异步任务完成后执行特定的操作。Promise对象有两个状态:已完成和已拒绝。当异步任务成功完成后,Promise对象就会变为已完成状态;如果异步任务失败,则Promise对象变为已拒绝状态。

手写Promise:揭开神秘面纱

现在,让我们一步步揭开手写Promise的神秘面纱。首先,我们创建一个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);
    });
  };

  executor(resolve, reject);
}

接下来,我们实现then方法。then方法接受两个参数:一个用于处理已完成状态的回调函数,另一个用于处理已拒绝状态的回调函数。

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

静态方法:Promise的锦上添花

Promise还提供了几个静态方法,包括resolve、reject、all和race。这些方法可以帮助我们更轻松地处理Promise。

resolve方法将一个值包装成一个已完成的Promise对象。

Promise.resolve(1).then((value) => {
  console.log(value); // 1
});

reject方法将一个值包装成一个已拒绝的Promise对象。

Promise.reject('error').then(null, (reason) => {
  console.log(reason); // 'error'
});

all方法接受一个Promise数组,并返回一个新的Promise对象。当所有Promise对象都变为已完成状态时,新的Promise对象也会变为已完成状态。

const promises = [
  Promise.resolve(1),
  Promise.resolve(2),
  Promise.resolve(3)
];

Promise.all(promises).then((values) => {
  console.log(values); // [1, 2, 3]
});

race方法接受一个Promise数组,并返回一个新的Promise对象。当任何一个Promise对象变为已完成或已拒绝状态时,新的Promise对象也会变为已完成或已拒绝状态。

const promises = [
  Promise.resolve(1),
  Promise.reject('error'),
  Promise.resolve(3)
];

Promise.race(promises).then((value) => {
  console.log(value); // 1
}, (reason) => {
  console.log(reason); // 'error'
});

结语

通过本文,你已经学会了如何手写Promise,并了解了它的then方法和静态方法。Promise是一个非常强大的工具,可以帮助你轻松处理异步任务。希望你能熟练掌握Promise,并将其应用到你的项目中。