在 ECMAScript 2015 (ES6)中,引入了 generator 函数。Generator函数是一种特殊的函数,可以被中断执行,随后又从中断的地方继续执行。这种特性可以用来实现异步操作、迭代器等功能。在 ECMAScript 2017 中,对 generator 函数进行了一些扩展,让其更加易用和强大。本文将介绍如何正确地使用 generator 函数,并且给出一些示例代码。
生成器函数的基本概念
Generator函数的定义方式与普通函数类似,但是添加了一个 *
,表示这是一个 Generator 函数。Generator 函数内部可以使用关键字 yield
来暂停执行,并将结果返回。调用 Generator 函数时,函数并不会立即执行,而是返回一个迭代器对象。可以通过调用迭代器对象的 next
方法来逐步执行 Generator 函数。
下面是一个简单的例子,展示了 Generator 函数的基本使用方法:
-- -------------------- ---- ------- --------- ------------- - ----- -- ----- -- ----- -- - ----- - - -------------- ---------------------- -- -- - ------ -- ----- ----- - ---------------------- -- -- - ------ -- ----- ----- - ---------------------- -- -- - ------ -- ----- ----- - ---------------------- -- -- - ------ ---------- ----- ---- -
在上面的代码中,我们定义了一个名为 myGenerator
的 Generator 函数,该函数内部有三个 yield
语句,返回了 1、2、3 三个值。通过调用 myGenerator
函数,我们获得了一个迭代器对象 g
,并且通过三次调用 g.next()
方法,分别获得了 1、2、3 三个值,并且最后一次调用后 done
属性为 true
,表示迭代器对象已经遍历完毕。
Generator 函数的新特性
Async 与 Await
在 ECMAScript 2017 中,引入了 async 和 await 关键字,可以方便地处理异步操作。async 表示一个异步函数,会返回一个 Promise 对象。await 则是在异步操作完成后,从 Promise 对象中提取出真正的值。
下面是一个简单的例子,展示了如何使用 async 和 await 来优化异步代码:
-- -------------------- ---- ------- -------- ----------- - ------ --- --------------- -- ------------------- ------- - ----- -------- ---------------- - ----- ------------ -- -- ---- -- ---------------------- ------------- - ----------------- -- -- ---------- --------------- ---- --
在上面的代码中,我们定义了一个实现了异步操作的 myPromise
函数,包含了 1000 毫秒的延迟。在 asyncOperation
函数中,我们通过添加 async 关键字来表示该函数是异步函数。在其内部,我们通过 await 语句来等待 myPromise
函数的完成,然后再输出一条信息。
Generator 函数的异步操作
在 Generator 函数中,我们可以通过 yield 语句来处理异步操作。下面是一个简单的例子,展示了如何使用 yield 语句来实现异步操作:
-- -------------------- ---- ------- --------- ------------- - ----- ------ - ----- ------------ ---------------------- --------- ---- --------- -------- - -------- ----------- - ------ --- --------------- -- ------------- -- ----------- ------- - ----- - - -------------- ----- ------- - --------------- -- -- --------- --- ------- -- ------------------- -- ---------------- -- ------ --------- --------
在上面的代码中,Generator 函数会先调用 myPromise
函数,并将其结果通过 yield
语句返回。在我们调用 g.next()
函数时,由于 myPromise
函数是异步的,因此返回的是一个 Promise 对象。我们可以通过 Promise 的 then
方法,等待 Promise 完成并获取结果,然后将结果传递给 g.next()
函数,最终输出结果。
for...of 循环
在 ECMAScript 2015 中,通过 Symbol.iterator
方法可以使一个对象成为可迭代对象,可以通过 for...of
循环来遍历该对象。在 ECMAScript 2017 中,可以通过 yield*
语句,简化对象迭代的代码。下面是一个简单的例子,展示了如何使用 yield*
语句来遍历一个数组:
function* getNumbers() { yield* [1, 2, 3]; } for (const number of getNumbers()) { console.log(number); } // 输出 1、2、3
在上面的代码中,我们定义了一个名为 getNumbers
的 Generator 函数。在该函数中,我们通过 yield*
语句,将数组 [1, 2, 3]
转换为迭代器对象,并将其返回。在 for...of
循环中,我们可以直接遍历 getNumbers()
函数返回的迭代器对象,并输出其中的每个元素。
总结
在 ECMAScript 2017 中,对 Generator 函数进行了扩展,使其更加容易使用和强大。我们可以将 Generator 函数与 async、await、for...of 等语法结合使用,来处理异步操作、对象迭代等场景。通过本文介绍的示例代码,我们学习了如何使用 Generator 函数,同时也为日后的实际项目开发提供了指导意义。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64607937968c7c53b0228e01