返回

Promise的秘密:揭开异步编程的神秘面纱(一)(基于Promise A+规范)

前端

Promise的本质和状态转换

Promise是一个用来处理异步操作的类。它提供了一种机制,允许你在异步操作完成时或失败时执行特定的回调函数。Promise有三种状态:等待态(pending)、成功态(fulfilled)和失败态(rejected)。

  • 等待态:这是Promise的初始状态。它表示异步操作还没有完成。
  • 成功态:当异步操作成功完成时,Promise会进入成功态。此时,你可以使用then方法来执行回调函数,并传入成功的结果。
  • 失败态:当异步操作失败时,Promise会进入失败态。此时,你可以使用catch方法来执行回调函数,并传入失败的原因。

Promise的状态转换是单向的。一旦Promise进入成功态或失败态,它就不会再回到等待态。

then方法、catch方法和finally方法

Promise提供了一些方法来处理状态转换和执行回调函数。最常用的方法是then、catch和finally。

  • then方法:then方法允许你在Promise进入成功态或失败态时执行回调函数。它接受两个参数:成功回调函数和失败回调函数。如果Promise进入成功态,则执行成功回调函数;如果Promise进入失败态,则执行失败回调函数。
  • catch方法:catch方法只在Promise进入失败态时执行回调函数。它接受一个参数:失败回调函数。如果Promise进入失败态,则执行失败回调函数。
  • finally方法:finally方法无论Promise进入成功态还是失败态,都会执行回调函数。它接受一个参数:回调函数。无论Promise进入哪种状态,都会执行回调函数。

微任务和宏任务

为了理解Promise是如何工作的,我们需要了解微任务和宏任务的概念。

  • 微任务:微任务是指在主事件循环中,在执行同步任务和宏任务之前执行的任务。它包括promise的回调函数、MutationObserver的回调函数和XMLHttpRequest的事件处理函数等。
  • 宏任务:宏任务是指在主事件循环中,在执行同步任务之后执行的任务。它包括setTimeout、setInterval和I/O操作等。

微任务的优先级高于宏任务。这意味着,当主事件循环中有微任务和宏任务时,微任务会优先执行。

Promise的实现

现在,我们来构建一个符合Promise A+规范的Promise实现。

class Promise {
  constructor(executor) {
    this.state = 'pending';
    this.result = undefined;
    this.onFulfilledCallbacks = [];
    this.onRejectedCallbacks = [];

    const resolve = (result) => {
      if (this.state !== 'pending') {
        return;
      }

      this.state = 'fulfilled';
      this.result = result;

      this.onFulfilledCallbacks.forEach((callback) => {
        callback(result);
      });
    };

    const reject = (reason) => {
      if (this.state !== 'pending') {
        return;
      }

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

      this.onRejectedCallbacks.forEach((callback) => {
        callback(reason);
      });
    };

    try {
      executor(resolve, reject);
    } catch (error) {
      reject(error);
    }
  }

  then(onFulfilled, onRejected) {
    return new Promise((resolve, reject) => {
      const handleFulfilled = (result) => {
        try {
          const fulfilledResult = onFulfilled(result);
          resolve(fulfilledResult);
        } catch (error) {
          reject(error);
        }
      };

      const handleRejected = (reason) => {
        try {
          const rejectedResult = onRejected(reason);
          resolve(rejectedResult);
        } catch (error) {
          reject(error);
        }
      };

      if (this.state === 'pending') {
        this.onFulfilledCallbacks.push(handleFulfilled);
        this.onRejectedCallbacks.push(handleRejected);
      } else if (this.state === 'fulfilled') {
        setTimeout(() => {
          handleFulfilled(this.result);
        }, 0);
      } else if (this.state === 'rejected') {
        setTimeout(() => {
          handleRejected(this.result);
        }, 0);
      }
    });
  }

  catch(onRejected) {
    return this.then(null, onRejected);
  }

  finally(onFinally) {
    return this.then(
      (result) => {
        onFinally();
        return result;
      },
      (reason) => {
        onFinally();
        throw reason;
      }
    );
  }
}

这就是一个符合Promise A+规范的Promise实现。它可以处理异步操作,并使用then、catch和finally方法来执行回调函数。

结语

Promise是一个非常强大的工具,它可以帮助你轻松地处理异步操作。通过本文,你已经了解了Promise的基本概念、状态转换、then方法、catch方法和finally方法,以及Promise的实现原理。希望这些知识能够帮助你更好地理解Promise,并在你的项目中使用它来编写出更简洁、更易读的代码。