十二、生成器
生成器其实就是一个特殊的函数。它主要用于异步编程。
1.生成器函数与迭代器
function * gen() {
console.log("Hello World")
}
gen()
这段代码并不会输出Hello World
,而是有输出下面的内容:
gen().next()
输出:
生成器函数使用next方法
此外,生成器函数还可以配合yield语句使用。yield语句是函数代码的分隔符,比如下面的代码中:
function * gen() {
console.log('segment 1')
yield 'A'
console.log('segment 2')
yield 'B'
console.log('segment 3')
yield 'C'
console.log('segment 4')
}
三个yield语句,将函数代码分成四个部分。通过
gen().next()
gen().next()
gen().next()
gen().next()
我们得到的是:
不是想要的结果
这不是我们想要的依次输出四段的结果,此时必须将gen()赋给一个变量,才能做顺序输出:
let iterator = gen()
iterator.next()
iterator.next()
iterator.next()
iterator.next()
顺序输出的结果
我们再输出下iterator和gen()看看:
iterator和gen()的区别
可以发现iterator是gen {<closed>}
而gen()是gen {<suspend>}
,尖括号中表示的是生成器函数不同的状态。
我们试着用适配迭代器对象的for...of循环来试用下gen()试试,就会发现
for (let v of gen()) {
v
console.log(v)
}
它输出的是:
结果
由上我们可以看出:生成器函数能生成一组值的序列,但每个值的生成基于每次请求,并不像标准函数那样立即生成。调用生成器时,不会立即执行函数体内的代码,会生成一个迭代器。
2.生成器函数的yield表达式返回值
我们将上述的生成器函数做些许修改:
function * gen(arg) {
console.log(arg)
let valA = yield 'A'
console.log(valA)
let valB = yield 'B'
console.log(valB)
}
let iterator = gen('my arguments')
console.log(iterator.next())
console.log(iterator.next())
网友评论