手写 Promise 的流程

阅读时长 14 分钟读完

本文将会介绍手写 Promise 的流程。Promise 是 JavaScript 中一种异步编程的解决方案。在异步操作中,使用回调函数来传递结果,但是回调函数嵌套过多,代码可读性较差。使用 Promise 可以解决这个问题。

什么是 Promise?

Promise 是一种 ECMAScript 6 引入的标准化异步编程的解决方案。Promise 代表一个异步操作的最终完成/失败及其结果值。

Promise 具有以下三个状态:

  • pending(进行中): 初始状态,可以转化为 fulfilled 或 rejected。
  • fulfilled(已成功): 操作成功完成,且有一个返回值,可以访问其对应的返回值。
  • rejected(已失败): 操作失败,有一个原因(reason)可以访问。

步骤一:创建 Promise 类

首先,创建一个 Promise 类,它包含一个构造函数,构造函数中传入一个函数参数executor,这个函数参数executor,是一个函数参数,就是整个 Promise 异步执行的地方。

步骤二:定义 Promise 状态和值

在 Promise 类中,需要定义 Promise 的状态、值和回调函数,如下代码所示:

-- -------------------- ---- -------
----- ------- -
  --------------------- -
    ----------- - ---------- -- ------- ---
    ---------- - ---------- -- ------- --
    ------------------------ - --- -- ------- ---------------
    ------------------------ - --- -- ------- --------------

    -- --
  -
-

步骤三:定义 resolve 和 reject 方法

在 Promise 类中,需要定义 resolve 和 reject 方法,用于改变 Promise 对象的状态和值。resolve 方法表示异步操作成功时将状态改为fulfilled,异步操作失败时将状态改为 rejected。

-- -------------------- ---- -------
----- ------- -
  --------------------- -
    ----------- - ----------
    ---------- - ----------
    ------------------------ - ---
    ------------------------ - ---

    ----- ------- - ------- -- -
      -- ------------ --- ---------- -
        ----------- - ------------
        ---------- - ------
        ------------------------------------- -- ------
      -
    --

    ----- ------ - -------- -- -
      -- ------------ --- ---------- -
        ----------- - -----------
        ---------- - -------
        ------------------------------------- -- ------
      -
    --

    --- -
      ----------------- --------
    - ----- --- -
      ----------
    -
  -
-

步骤四:定义 then 方法

then 方法用于在 Promise 对象状态改变时注册回调函数,then 方法接收两个参数 onFulfilled 和 onRejected。onFulfilled 表示 Promise 对象变为 fulfilled 状态时的回调函数;onRejected 表示 Promise 变为 rejected 状态时的回调函数。

-- -------------------- ---- -------
----- ------- -
  --------------------- -
    ----------- - ----------
    ---------- - ----------
    ------------------------ - ---
    ------------------------ - ---

    ----- ------- - ------- -- -
      -- ------------ --- ---------- -
        ----------- - ------------
        ---------- - ------
        ------------------------------------- -- ------
      -
    --

    ----- ------ - -------- -- -
      -- ------------ --- ---------- -
        ----------- - -----------
        ---------- - -------
        ------------------------------------- -- ------
      -
    --

    --- -
      ----------------- --------
    - ----- --- -
      ----------
    -
  -

  ----------------- ----------- -
    ----------- - ------ ----------- --- ---------- - ----------- - ------- -- ------
    ---------- -
      ------ ---------- --- ----------
        - ----------
        - -------- -- -
            ----- -------
          --
    --- -------- - --- ----------------- ------- -- -
      -- ------------ --- ------------ -
        ------------- -- -
          --- -
            --- - - ------------------------
            ----------------------------- -- -------- --------
          - ----- --- -
            ----------
          -
        -- ---
      -
      -- ------------ --- ----------- -
        ------------- -- -
          --- -
            --- - - -----------------------
            ----------------------------- -- -------- --------
          - ----- --- -
            ----------
          -
        -- ---
      -
      -- ------------ --- ---------- -
        -------------------------------- -- -
          ------------- -- -
            --- -
              --- - - ------------------------
              ----------------------------- -- -------- --------
            - ----- --- -
              ----------
            -
          -- ---
        ---
        -------------------------------- -- -
          ------------- -- -
            --- -
              --- - - -----------------------
              ----------------------------- -- -------- --------
            - ----- --- -
              ----------
            -
          -- ---
        ---
      -
    ---
    ------ ---------
  -
-

步骤五:定义 resolutionProcedure 方法

在 then 方法中的 onFulfilled 和 onRejected 的回调函数中,需要处理 Promise 的值和新 Promise 的状态。如果返回值是一个 Promise 对象,需要等待执行完后,再处理新 Promise 对象的状态和值。resolutionProcedure 方法就是用来处理这个过程。

-- -------------------- ---- -------
----- ------------------- - ---------- -- -------- ------- -- -
  -- -- - --- ------- --
  -- --------- --- -- -
    ------ ---------- ------------------- ----- -------- --- -----------
  -
  --- ------ - ------
  -- -- -- ---- -- ------- - --- -------- -- ------ - --- ------------ -
    --- -
      --- ---- - -------
      -- ------- ---- --- ----------- -
        ----------
          --
          --- -- -
            -- -------- -------
            ------ - -----
            ----------------------------- -- -------- --------
          --
          --- -- -
            -- -------- -------
            ------ - -----
            ----------
          -
        --
      - ---- -
        -----------
      -
    - ----- --- -
      -- -------- -------
      ------ - -----
      ----------
    -
  - ---- -
    -----------
  -
--

示例代码

使用手写的 Promise,实现一个异步加载图片的方法 loadImg。

-- -------------------- ---- -------
----- ------- -
  --------------------- -
    ----------- - ----------
    ---------- - ----------
    ------------------------ - ---
    ------------------------ - ---

    ----- ------- - ------- -- -
      -- ------------ --- ---------- -
        ----------- - ------------
        ---------- - ------
        ------------------------------------- -- ------
      -
    --

    ----- ------ - -------- -- -
      -- ------------ --- ---------- -
        ----------- - -----------
        ---------- - -------
        ------------------------------------- -- ------
      -
    --

    --- -
      ----------------- --------
    - ----- --- -
      ----------
    -
  -

  ----------------- ----------- -
    ----------- - ------ ----------- --- ---------- - ----------- - ------- -- ------
    ---------- -
      ------ ---------- --- ----------
        - ----------
        - -------- -- -
            ----- -------
          --
    --- -------- - --- ----------------- ------- -- -
      -- ------------ --- ------------ -
        ------------- -- -
          --- -
            --- - - ------------------------
            ----------------------------- -- -------- --------
          - ----- --- -
            ----------
          -
        -- ---
      -
      -- ------------ --- ----------- -
        ------------- -- -
          --- -
            --- - - -----------------------
            ----------------------------- -- -------- --------
          - ----- --- -
            ----------
          -
        -- ---
      -
      -- ------------ --- ---------- -
        -------------------------------- -- -
          ------------- -- -
            --- -
              --- - - ------------------------
              ----------------------------- -- -------- --------
            - ----- --- -
              ----------
            -
          -- ---
        ---
        -------------------------------- -- -
          ------------- -- -
            --- -
              --- - - -----------------------
              ----------------------------- -- -------- --------
            - ----- --- -
              ----------
            -
          -- ---
        ---
      -
    ---
    ------ ---------
  -
-

----- --------- - ----- --
  --- ----------------- ------- -- -
    ----- --- - --- --------
    ---------- - -- -- -
      -------------
    --
    ----------- - --- -- -
      ----------
    --
    ------- - ----
  ---

----------------------------------------------------- -- -
  -------------------------------
---

总结

本文介绍了手写 Promise 的流程,包括创建 Promise 类、定义 Promise 状态和值、定义 resolve 和 reject 方法、定义 then 方法和定义 resolutionProcedure 方法。使用手写的 Promise,可以实现异步操作的解决方案,提高代码的可读性。

来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64e0518af6b2d6eab3b66fee

纠错
反馈