Generator 函数是 ES6 中新加入的一个重要特性,其基本概念是用于生成 Iterator 的一种新型函数,而在 ES7 中,Generator 函数又进一步完善和加强了。
什么是 Generator 函数?
Generator 函数的定义方式是在 function 后面加上一个 * 号,即 function*。Generator 函数可以看做是一类特殊的函数,它可以暂停执行,后面又可以恢复执行,同时还可以向外界传递数据。
以一个简单的示例来说明:
-- -------------------- ---- ------- --------- --------------- - --------------------- ----- -- ---------------------- - ----- --------- - ---------------- ----------------- -- -- --------- - ------ -- ----- ----- - ----------------- -- -- ---------- - ------ ---------- ----- ---- -
我们可以看到,使用 Generator 函数生成一个 generator 对象后,调用 next 方法会返回一个对象,其中包含了 value 和 done 两个属性。
调用 next 方法时,Generator 函数内的代码执行到 yield 关键字位置就会暂停,以生成一个 value 值并将 done 值置为 false 返回给调用方。再次调用 next 方法时,Generator 函数内的代码会从上次暂停的位置开始恢复执行,直到遇到下一个 yield 关键字或函数结束位置为止。
Generator 函数的应用
1. 异步编程
Generator 函数在异步编程中有很大的用处,可以轻松达到协同的效果,简化异步代码的编写。
以一个接口请求为例,我们可以使用 Generator 函数来实现异步请求的同步执行:
-- -------------------- ---- ------- --------- --------- - ----- ----- - ----- ------------ ----- ----- - ----- ------------ ------ ------- ------- - -------- -------------- - ----- --- - ------------ -------- ---------- - ----- ------ - --------------- -- ------------- ------ ------------- ------------------------ -- ------------ - ------ ------- - -------------
这个例子中,我们定义了一个 request Generator ,并使用 run 函数来执行它。在 request 中,我们使用了 yield 关键字对异步接口请求进行了暂停和恢复操作,在 run 函数中,我们使用了递归函数实现了异步请求的同步流程。
2. 状态机
Generator 函数也可以作为状态机使用,进一步简化代码的编写。
-- -------------------- ---- ------- ----- ------ - - ---------- --------- ----- - ----- ------ - -- ---- - ---- --- - ----- --------- --- -- --- - -- -- -------- --------------- ---- - ----- --- - ----------- -------- ---------- - ----- ------ - --------------- -- ------------- ------ ------------- ------------------------ -- ------------ - ------ ------- - -------------------------- ---- -- ------- --- -- -- ------ --- -- ------ ------
在这个例子中,我们定义了一个状态机对象 states ,其中 initState 是一个 Generator 函数。通过 runState 函数,我们实现了状态机的运行,每次执行会返回当前状态加 10 后的值,直到状态转移到 finish。
ES7 中新增的 Generator 函数特性
在 ES7 中,我们发现 Generator 函数的应用进一步扩展和加强,下面介绍一下几个新增的特性。
1. generator 星号表达式
generator 星号表达式(starred generator)是针对一些生成器迭代器语法,简单来说,就是可以将一个 Generator 函数中所有 yield 子表达式处的值全部迭代出来。
以一个示例代码为例:
-- -------------------- ---- ------- --------- --------------- - ----- -- ----- -- ----- -- - ----- ------- ---------- - ---------------- ------------------- -- - -------------------- -- --- --
我们可以使用解构赋值语法,将 Generator 函数中 yield 关键字生成的所有值迭代出来。
2. 生成器的异步方法
在 ES7 中,我们可以使用 Generator 函数来执行异步代码,并将异步操作封装在构造函数中:
-- -------------------- ---- ------- ----- --------- - ----- ----------- - ----- ---- - ----- -------------------- ----- ---------- - - ----- ------- - --- ------------ ----- ---- - ----- --------------------------------
我们可以通过 async 关键字和 yield 表达式,将异步操作包装在类方法的 Generator 函数中,并通过 next 方法获取异步操作的返回结果。
3. for-await-of 循环
在 ES7 中,我们可以使用 for-await-of 循环遍历 Iterator 或异步 Generator 函数生成的 iterator。
以代码为例:
-- -------------------- ---- ------- ----- --------- --------------- - --- ------ --- -- ----- - ----- ----- ----------- - - ------ -- -- - ----- ---- - ---------- --------- ---------- --- ----- ------ -------- -- ---------------- - ----- ------ - ----- ---------------- -------------------- - -----
我们定义了一个 async generator 函数 fetchURLs,其中使用 for-of 循环请求 urls 中的接口,返回一个 response。
在代码中,我们使用了 for-await-of 循环遍历 fetchURLs 返回的 Iterator,并使用 await 操作符获取 response 中的返回结果。
总结
Generator 函数是一种强大的函数类型,可以用于异步编程和状态机的实现。在 ES7 中,新增的特性和加强,使得 Generator 函数在前端开发中的应用变得更加重要和广泛。
我们应该深入理解 Generator 函数的特点和应用场景,以充分发挥它的威力,提高前端开发效率。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/648720f148841e98945cbfd9