generator的用法 & async-await

generator的用法 & async-await
Tomgenerator用法实现以及async-await
什么是generator
在 JavaScript 中,Generator 是一种特殊的函数,它可以产生多个值的序列。Generator 函数使用 function* 声明,并通过 yield 关键字 来定义每个值的生成步骤。
Generator 函数可以被看作是一个状态机,它可以在每次调用 next() 方法时暂停和恢复执行。每次调用 next() 方法时,Generator 函数会执行到下一个 yield 关键字处,并将 yield 后面的值作为结果返回。当再次调用 next() 方法时,Generator 函数会从上次暂停的位置继续执行,直到遇到下一个 yield 关键字或函数结束。
1 | function* gen() { |
通过调用 gen() 创建了一个 Iterator。每次调用 it.next() 方法,Generator 函数会执行到下一个 yield 关键字处,并返回一个包含 value 和 done 属性的对象。value 属性表示生成的值,done 属性表示 Generator 函数是否已经执行完毕。
通过连续调用 it.next() 方法,我们可以依次获取生成的值。当 Generator 函数执行完毕后,再次调用 next() 方法将返回 undefined。
js执行是先走等号右边的,遇到yield就停止了,如果想传递参数,下一次调用next传递的参数是上一个yield的值
需要注意的是,Generator 函数只是一种语法上的特殊函数,它不会立即执行,而是返回一个可迭代的 Generator 对象。我们需要通过调用 next() 方法来逐步获取生成的值。
generator的异步应用
上面例子中我们可以看到 generator函数可以通过 yield 关键字暂停异步操作,并在操作完成后恢复执行。
假如有两个文件文件名分别为name.txt 、 age.txt
1 | // name.txt |
有了上面的特性我们希望利用generator来这样写我们的异步代码
1 |
|
这样写起来有点虽然好,但是调用起来应为是promise,需要我们每次手动去.then (太麻烦了)
1 | let it = readResult() |
终于 TJ 大佬写了个 co库,解决了这个问题,我们只需引入这个 co库 然后 co库 执行传入我们自定义的generator函数即可
1 | const co = require('co') // 第三方模块 |
这样是不是就简单多了,我们可以想象这个库是如何实现的:
可以调用.then方法说明返回的是一个promise
co库内部会循环迭代promise
本质来讲 co 库就是帮我实现了上面的循环迭代 promise
1 | function co(it){ |
async + await
上面的读取方法如果换成async + await 会写成这样
1 | const fs = require('fs/promises') // 这里会把方法promise化 |
一比较就会发现,async函数就是将 Generator 函数的星号(*)替换成async,将yield替换成await,仅此而已。
await就是相当于co库的功能,帮我们迭代执行async函数中的方法
async + await 相当于 generator + co库 的语法糖
参考文章:Generator 函数的异步应用 、 async 函数













