Generator是什么?
Generator 函数是 ES6 提供的一种异步编程解决方案。
官方描述:
1、Generator 对象由
生成器函数
返回并且它符合可迭代协议
和迭代器协议
;2、
生成器函数
在执行时能暂停,后面又能从暂停处继续执行;
第一句话告诉我们 Generator 对象不能够通过构造函数那样new出来,而是由生成器函数
生成,并且可以用 for... of...
进行遍历;
第二句话的意思是 生成器函数
内的代码需要特定的方式执行,而且在执行过程中可以停住,更可以继续执行。
结合代码来理解官方描述:
// 1.生成器函数的基本写法:functon关键字后面加*号,代表这是一个生成器函数
// 2.在生成器函数内部通过 yield 关键字暂停代码的执行
function* func() {
yield 'study'
yield 'Generator'
yield 'function'
}
// 3.调用生成器函数 ,返回一个 Generator 对象 f
// (⚠️注意:此时调用func函数时,它内部的代码不会执行)
const f = func()
//4.调用 Generator 对象的 next() 方法,func 内部代码会自上而下执行,遇到第 yield 关键字时暂停执行,并且返回 yield 后面的表达式
f.next() //{value: 'study', done: false}
使用for... of...遍历 Generator 对象 f
for (const iterator of f) {
console.log(iterator)
}
输出结果:
Generator 的详细案例演示
Generator-核心语法
- 如何定义生成器函数:
- 如何获取
generator
对象 yield
表达式的使用- 通过
for... of...
获取每一个yield
的值
// 1. 通过function* 创建生成器函数
function* foo() {
// 遇到yield表达式时会暂停后续的操作
yield 'a'
yield 'b'
yield 'c'
return 'd'
}
// 2. 调用函数获取生成器
const f = foo()
// 3. 通过next方法获取 yield 之后的表达式结果,会被包装到一个对象中
// 执行一次next 即可获取一次 yield之后的表达式结果
const res1 = f.next()
console.log(res1)// {value: 'a', done: false}
const res2 = f.next()
console.log(res2)// {value: 'b', done: false}
const res3 = f.next()
console.log(res3)// {value: 'c', done: false}
// 最后一次可以拿到return的结果
const res4 = f.next()
console.log(res4)// {value: 'd', done: true}
// done 为true之后,获取到的value为undefined
const res5 = f.next()
console.log(res5)// {value: undefined, done: true}
// 4. 通过for of 获取每一个yield之后的值,
const f2 = foo()
for (const iterator of f2) {
console.log(iterator)
}
输出结果:
Generator-id生成器
需求: 使用Generator
实现一个id生成器
思路:
- 定义生成器函数
- 内部使用循环,通过
yield
返回id
并累加
// 1. 通过function* 创建生成器函数
function* generatorId() {
let id = 0
// 无限循环
while (true) {
// id累加并返回
yield id++
}
}
// 2. 调用函数获取生成器
const idMaker = generatorId()
// 3. 需要id的时候 通过next获取即可
const { value: id1 } = idMaker.next()
console.log(id1)
const { value: id2 } = idMaker.next()
console.log(id2)
输出结果:
生成器函数内部的代码会在调用
next
方法时执行,利用这一特点,可以实现任意的生成器,需要时调用next
即可获取结果。
总结
学习 Generator 的核心思路记住以下两点:
- 可以通过生成器函数(
function* xxx(){}
)来生成Generator
对象; - 通过
Generator
对象的next
方法可以获取yield
表达式之后的结果;