💤
多个迭代器
从语法使用方面来看就,通过一个迭代器控制生成器的时候,似乎是在控制声明的生成器函数。但是有一个细微之处很容易忽略:每次构建一个迭代器,实际上就隐式构建了一个生成器的一个实例,通过这个迭代器来控制的是这个生成器实例。
同一个生成器的多个实例可以同时运行,它们甚至可以彼此交互:
javascript
var z = 1
function* foo() {
var x = yield 2
z++
var y = yield x * z
console.log(x, y, z)
}
var it1 = foo()
var it2 = foo()
var val1 = it1.next().value // 2
var val2 = it2.next().value // 2
val1 = it1.next(val2 * 10).value // 40
val2 = it2.next(val1 * 5).value // 600
it1.next(val2 / 2) //
it2.next(val1 / 4) //*foo()的两个实例同时启动,两个next()分别从yield 2语句得到值 2。it1.next(val2 * 10),也就是it1.next(20),发送到第一个生成器实例it1,20会替换上一个yield及后面的表达式 ——var x = 20,同时从下一个yield语句得到值x * z——20 * 2,将val1设置为 40。it2.next(val1 * 5),也就是it2.next(200),发送到第二个生成器实例it2,200会替换上一个yield及后面的表达式 ——var x = 200,同时从下一个yield语句得到值x * z——200 * 3,将val2设置为 600。it1.next(val2 / 2),也就是it1.next(600 / 3),发送到第一个生成器实例it1,200会替换上一个yield及后面的表达式 ——var y = 300,然后打印出 x y z 的值分别是 20 300 3。it2.next(val1 / 4),也就是it2.next(40 / 4),发送到第二个生成器实例it2,10会替换上一个yield及后面的表达式 ——var y = 10,然后打印出 x y z 的值分别是 200 10 3。
generator -> async/await
javascript
function delay(time, val) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(val)
}, time)
})
}
function* foo() {
const r2P = yield delay(1000, 'res2')
const r3P = yield delay(500, 'res3')
return [r2P, r3P]
}
function* bar() {
const r1 = yield delay(1000, 'res1')
const res = yield* foo()
console.log('res:', r1, res) // res: res1 [ 'res2', 'res3' ]
}
const it = bar()
const p0 = it.next().value
p0.then(res => {
const p1 = it.next(res).value
p1.then(res => {
const p2 = it.next(res).value
p2.then(res => {
it.next(res)
})
})
})25 行及以后的代码,可以封装为一个工具方法,用于自动处理 resolve/reject 以及错误处理。但是我不会。

