Generator 对象是由一个 generator function 返回的,并且它符合 可迭代协议 和 迭代器协议。
js
function* foo() {
for(let i = 0; i < 3; i++) {
yield i
}
}
console.log(foo()) // foo {<suspended>}
let f = foo()
console.log(f.next()) // {value: 0, done: false}
console.log(f.next()) // {value: 1, done: false}
console.log(f.next()) // {value: 2, done: false}
console.log(f.next()) // {value: undefined, done: true}
注意:generator function
不能作为构造函数使用;yield 关键字只能在 generator function
里面使用。
js
function* gen(args) {
args.forEach(item => {
yield item // Uncaught SyntaxError: Unexpected identifier
})
}
js
// 稍微复杂点的
function* gen(x) {
let y = 2 * (yield(x + 1))
let z = yield(y / 3)
return x + y + z
}
let g = gen(5)
console.log(g.next().value) // 6
console.log(g.next(12).value) // 8 y=24
console.log(g.next(13).value) // 42 z=13 x=5 y=13
next() 传入的参数作为上一次 yield 的返回值。
js
// 场景
function* count(x = 1) {
while(true) {
if(x % 7 === 0) {
yield x
}
x++
}
}
let n = count()
console.log(n.next().value) // 7
console.log(n.next().value) // 14
使用 generator function
配合异步:
js
function ajax(url, cb) {}
function request(url) {
ajax(url, res => {
g.next(res)
})
}
function* gen() {
let res1 = yield request('./a.json')
console.log(res1)
let res2 = yield request('./b.json')
console.log(res2)
let res3 = yield request('./c.json')
console.log(res3)
}
let g = gen()
g.next()
上面的代码很难理解。