开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第22天,点击查看活动详情
在 JS 中,Generator 称之为生成器。它是 ES6 为我们提供的一种异步编程解决方案,除此之外,异步的解决方案还有:
- 回调函数
- generator 函数
- Promise 对象
- async/await
Generator
Generator 函数会返回一个遍历器对象,它具有 Symbol.iterator 属性。
函数的具体形式是:
- 函数名之前有一个星号
- 函数内部使用
yield表达式 - 不能使用箭头函数创建生成器函数
- Generator 本身并不会自动进行
next操作,代码中通过手调用 .next() 函数遍历到下一个内部状态- 当执行函数遇到
yield关键词,会将 yield 后面的值作为 value 的值返回 - 每执行一次 next() 函数,继续向下执行,遇到 yield 关键词为止
- 如果没有遇到 yield 关键字,继续执行,直到执行到 return 语句
- 再执行 next(),此时会将 undefined 作为 value 的值返回
- 当执行函数遇到
function * myFunc() {
yield 'apple'
yield 'banana'
return 'orange'
}
const f = myFunc()
console.log(f.next()) // { value: apple, done: false }
console.log(f.next()) // { value: banana, done: false }
console.log(f.next()) // { value: orange, done: true }
console.log(f.next()) // { value: undefined, done: true }
从运行结果中,可以看到每一步结果是以 { value: , done: } 的形式输出,value 表示当前返回的值,done 表示完成状态(true / false)
此外,还可以使用 for...of对生成器进行遍历,因为Generator 函数会返回一个遍历器对象(Iterator)
function* func() {
yield 100;
yield 200;
yield 300;
yield 400;
yield 500;
return 600;
}
for (let item of func()) {
console.log(item);// 100 200 300 400 500
}
运行结果:
Async/Await 和 Generator
async/await 是 Generator 的语法糖,因为实际上 async 函数就是把 Generator 里的 * 替换成 async,将 yield 替换成了 await,整个流程不需要手动调用 next()
关于 Async/Await 的详细介绍可参考之前的文章: JS进阶 | async/await和Promise的那些事