ES6 中 Generator 函数的工作原理及使用方式

什么是 Generator 函数

Generator 函数是 ES6 中的一种新类型的函数,它可以通过 function* 关键字定义,同时可以使用 yield 关键字来控制函数的执行流程。Generator 函数可以被视为一个状态机,它的执行过程可以被暂停和恢复。

Generator 函数的工作原理

Generator 函数的工作原理可以通过一个简单的示例来说明:

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

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

上面的示例中,generatorFunction 是一个 Generator 函数,它定义了一个状态机,每次执行到 yield 关键字时会暂停函数的执行,并返回一个包含 valuedone 两个属性的对象。value 表示当前执行到的值,done 表示当前状态机是否已经执行完毕。

在上面的示例中,我们首先通过 generatorFunction() 函数创建了一个 Generator 对象 generator,然后依次调用了 generator.next() 方法三次。在第一次调用时,generatorFunction 函数执行到了第一个 yield 关键字,暂停了函数的执行,并返回了一个包含 valuedone 两个属性的对象,此时 value 的值为 1,done 的值为 false。在第二次调用时,generatorFunction 函数从上一次暂停的地方继续执行,执行到了第二个 yield 关键字,再次暂停函数的执行,并返回了一个包含 valuedone 两个属性的对象,此时 value 的值为 2,done 的值为 false。在第三次调用时,generatorFunction 函数从上一次暂停的地方继续执行,执行到了函数的结尾,此时没有遇到 yield 关键字,函数执行完毕,并返回一个包含 valuedone 两个属性的对象,此时 value 的值为 undefined,done 的值为 true。

Generator 函数的使用方式

Generator 函数的使用方式非常灵活,可以用于异步编程、迭代器和状态机等多种场景。下面分别介绍这些场景下 Generator 函数的使用方式。

异步编程

Generator 函数可以很方便地实现异步编程,例如:

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

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

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

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

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

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

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

上面的示例中,delay 函数返回一个 Promise 对象,该对象会在指定的时间后解决,并返回解决结果。asyncFunction 函数是一个 Generator 函数,它依次调用了两次 delay 函数,并在每次调用后使用 yield 关键字暂停函数的执行。runAsyncFunction 函数负责启动 asyncFunction 函数,并在每次 yield 关键字返回的 Promise 解决后继续执行 asyncFunction 函数。

迭代器

Generator 函数可以被视为一个迭代器,可以使用 for...of 循环来遍历 Generator 函数生成的值,例如:

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

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

上面的示例中,fibonacci 函数是一个 Generator 函数,它可以无限生成斐波那契数列。使用 for...of 循环可以遍历 fibonacci 函数生成的值,当生成的值大于 1000 时,退出循环。

状态机

Generator 函数可以被视为一个状态机,可以通过 yield 关键字来控制状态的转移,例如:

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

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

上面的示例中,stateMachine 函数是一个状态机,它可以根据当前的状态执行不同的操作。使用 yield 关键字可以控制状态的转移,例如在 start 状态下使用 yield 关键字返回 step1 状态,然后在 step1 状态下使用 yield 关键字返回 step2 状态,以此类推。在 end 状态下,stateMachine 函数执行完毕并返回。

总结

Generator 函数是 JavaScript 中非常有用的一个新特性,它可以用于异步编程、迭代器和状态机等多种场景。通过本文的介绍,我们可以了解到 Generator 函数的工作原理和使用方式,并通过示例代码深入理解 Generator 函数的应用。如果你还没有尝试过使用 Generator 函数,那么不妨在下一个项目中尝试一下吧!

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65f270a52b3ccec22fb07b22