Skip to content
On this page

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()

上面的代码很难理解。

Released under the MIT License.