JavaScript 是一门弱类型语言,支持多种不同的编程范式,其中函数式编程是一个重要的方向。JS 中有一种特殊的函数叫做 Generator 函数,它依据 ECMAScript 6 标准推出,能够返回一个迭代器,并且可以用异步编程方式控制它的执行。在 ECMAScript 2017 中,Async 函数被引入,它可以帮助开发者更方便地书写异步代码,使用 await 语法糖代替 Generator 函数中的 yield 语句。本文将介绍如何实现 Generator 函数与 Async 函数的相互转换,帮助读者更好地理解这两种函数的特性,并为大家提供一些示例代码。
Generator 函数
Generator 函数是 JavaScript 中的一种特殊函数,可以使用 *
关键字声明,其内部可以使用 yield 语句暂停函数执行,并且可以在之后恢复。以下是一个简单的 Generator 函数示例:
function* foo() { yield 1; yield 2; yield 3; }
我们可以通过调用 foo()
得到一个迭代器对象,接着可以调用 next()
方法去控制它的执行,当执行到 yield
语句的时候函数就会被暂停,此时返回的结果会被包装在 yield 表达式的值里面,直到下一次执行 next()
方法时恢复执行。以下是一个调用 Generator 函数的示例代码:
const generator = foo(); console.log(generator.next().value); // 1 console.log(generator.next().value); // 2 console.log(generator.next().value); // 3
Async 函数
Async 函数是 ECMAScript 2017 中引入的新特性,可以让开发者更方便地书写异步代码,它可以看做是 Generator 函数的语法糖,采用 async/await
关键字完成。以下是一个简单的 Async 函数示例:
async function foo() { const result = await Promise.resolve(1); return result; }
可以使用 async
关键字声明一个 Async 函数,其中使用 await
关键字来等待 Promise 解决后的结果,并使用 return 语句返回结果。以下是调用 Async 函数的示例代码:
foo().then(result => { console.log(result); // 1 });
Generator 函数与 Async 函数的相互转换
在实际开发过程中,我们可能需要将一个 Generator 函数转换成 Async 函数或反之。下面分别介绍 Generator 函数向 Async 函数的转换以及 Async 函数向 Generator 函数的转换。
Generator 函数向 Async 函数的转换
将 Generator 函数转换成 Async 函数的过程比较简单,只需要将所有的 yield
语句都改成 await
语句即可,另外需要加上 async
关键字来声明函数为 Async 函数。以下是一个将 Generator 函数转换为 Async 函数的示例代码:
-- -------------------- ---- ------- --------- ----- - ----- ------------------- ----- ------------------- ----- ------------------- - ----- -------- ----- - --- ----- ------ ----- -- ------ - ------------------- - -
我们将 Generator 函数 foo()
转换为 Async 函数 bar()
,在 for await...of
循环中使用 foo()
返回的迭代器进行遍历,同时需要注意 for await...of
循环在遍历结束后会自动调用迭代器的 return()
方法来确保迭代器被正确关闭。
Async 函数向 Generator 函数的转换
将 Async 函数转换为 Generator 函数稍微麻烦一些,需要手动创建一个 Generator 对象,然后将 Async 函数中的所有异步操作都封装在 Promise 中,使用 yield 语句代替 await 关键字。以下是一个将 Async 函数转换为 Generator 函数的示例代码:
-- -------------------- ---- ------- ----- -------- ----- - ----- ------ - ----- ------------------- ------ ------- - --------- ----- - ----- ------ - ----- ----------------- -- -------- -------------------- - ----- --------- - ------ ---------------------------------- -- ------------------------
我们将 Async 函数 foo()
转换为 Generator 函数 bar()
,在 Generator 函数中暂停执行,并使用 yield
语句返回异步操作的结果,在 Generator 对象中使用 then()
方法来恢复生成器的执行并传入异步操作的结果。这个过程需要额外使用一个迭代器对象来控制执行的流程。
总结
本文介绍了 ECMAScript 2019 中 Generator 函数与 Async 函数的特性,并提供了相关的转换示例代码。我们经过了实际的应用,可以发现 Generator 函数在异步编程中是一种非常重要的工具,可以有效地控制异步代码的执行流程。与之相对的是 Async 函数,它可以帮助开发者更加方便地书写异步代码,语法更加清晰易懂。这两种函数都有其独特的优势,在实际开发中需要结合实际需求选择使用。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64f529c5f6b2d6eab3dd931d