ES6 引入了 Generator 技术,允许开发者编写基于迭代协议的函数,可以控制函数的执行流程。在 ES10 中,Generator 技术进一步完善,增加了 Async Generator,可以用于更灵活的异步编程。
Generator
Generator 是一个迭代协议的函数,可以暂停和恢复函数的执行。Generator 函数通过使用 yield
关键字,允许开发者在不中断函数执行的情况下,从函数中返回一个值。
Generator 函数示例:
function* generatorExample() { yield 'foo'; yield 'bar'; yield 'baz'; }
使用 for…of
循环遍历 Generator 函数,获取每一个 yield
的值:
for (let value of generatorExample()) { console.log(value); } // output: 'foo' 'bar' 'baz'
如果需要在 Generator 函数中接受参数,可以在调用 Generator 实例时传递参数:
-- -------------------- ---- ------- --------- ----------------------------- - ----- - - -- ----- - - -- ----- - - -- - --- --- - ------------------------------ ------------------------------ -- ------- - ------------------------------ -- ------- - ------------------------------ -- ------- -展开代码
除了 next()
方法,Generator 还有其他方法,如 return()
和 throw()
,可以用于控制函数的执行流程。
Async Generator
Async Generator 是一种异步可迭代协议,是 Generator 的扩展,可以返回异步值或 Promise,并且可以使用 await
表达式来处理异步调用。
Async Generator 函数示例:
async function* asyncGeneratorExample() { yield await Promise.resolve('foo'); yield await Promise.resolve('bar'); yield await Promise.resolve('baz'); }
使用 for await…of
循环遍历 Async Generator 函数,获取每一个异步 yield
的值:
async function logAsyncGenerator() { for await (let value of asyncGeneratorExample()) { console.log(value); } } logAsyncGenerator(); // output: 'foo' 'bar' 'baz'
示例代码
一个基于 async/await 和 Async Generator 技术的异步数据获取示例:
-- -------------------- ---- ------- ----- --------- -------------- - --- - --- -------- - ----- ----------- --- ---- - ----- ---------------- ----- ----- - ----- ----- - -------------------- -------- ----- - - ----- - - ----- -------- ------------- - --- ----- ---- ---- -- ----------------------- - ------------------ - - ------ - - --------------展开代码
上述代码中,fetchData()
函数是一个 Async Generator,通过 fetch()
和 await
关键字从指定的 API 获取数据并解析 JSON。在 processData()
函数中,使用 for await…of
循环遍历 fetchData()
获取的数据。
总结
在 ES10 中,通过 Generator 和 Async Generator 技术,开发者可以编写更灵活、更高效的异步代码。虽然这两种技术可能会增加代码复杂度,但是在需要处理异步数据流时仍然是非常有用的。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/6649570dd3423812e4826b12