function* bar () {
yield 1
yield 2
}
function* foo () {
yield 3
// 这边如果没有手动去遍历 `bar()` 返回的迭代器, `foo` 的下一个 `next` 函数就会执行到 `yield 4` 了
bar()
yield 4
}
const it = foo()
for (let value of it) {
console.log(value)
}
// 3 4
手动遍历:
function* bar () {
yield 1
yield 2
}
function* foo () {
yield 3
for (let value of bar()) {
yield value
}
yield 4
}
const it = foo()
for (let value of it) {
console.log(value)
}
// 3 1 2 4
使用 yield* 表达式:
function* bar () {
yield 1
yield 2
}
function* foo () {
yield 3
yield* bar()
yield 4
}
const it = foo()
for (let value of it) {
console.log(value)
}
// 3 1 2 4
概念
一种异步编程的解决方案,与传统函数的语法、行为完全不同
语法
function
关键字与函数名之间加个*
号。内部使用
yield
关键字,执行后返回一个迭代器(Iterator
),没错,就是用next
方法去遍历的迭代器:可以使函数“暂停”在某个阶段,等到执行了
next
方法后再继续执行。Generator 函数返回的迭代器在没有执行
next
是不会执行的:另外注意,
yield
关键字在其他表达式中,需要用括号包起来,不然会报错:for...of 循环
既然是 Iterator ,就可以用
for...of
循环来遍历它:next 函数的参数
在执行
next
时,如果给它传一个参数,这个参数会作为上一个yield
表达式的返回值。如果不传,其实就相当于传了
undefined
Generator.prototype.throw()
可以在 Generator 函数内部抛出一个错误,如果 Generator 内部没有处理,则会抛出到外部:
Generator.prototype.return()
相当于提前把这个迭代器结束遍历,即返回的
done
变为true
return
的第一个参数可以指定 value 的值:next, throw, return
三个函数其实可以理解为,把执行函数时起点的
yield
替换成了不同的语句:yield* 表达式
如果在 Generator 函数内部调用 Generator 函数,可以用
yield*
表达式,这样外层在遍历 Generator 时,遇到内部的 Generator 函数,会转而进入内部函数遍历,不会跳过:手动遍历:
使用
yield*
表达式:作为对象属性
Generator 函数作为对象属性的写法:
this
由于 Generator 函数返回的是一个 Iterator ,而不是 this 对象,因此在 Generator 函数内绑定在
this
上的属性都是无效的:此外, Generator 函数也不能作为构造函数而使用
new
命令:Generator 与协程、上下文,应用
这部分见峰哥的文章吧。
参考
http://es6.ruanyifeng.com/#docs/generator