是一种特殊的函数,可以按需一个接一个的产生值,可以用来进行异步编程ES6
语法
在 function 后面加 *
,函数体内使用 yield
function* myGenerate() {
yield 1
yield 2
return 3
}
let g = myGenerate()
g.next()
调用 Generator 函数,返回一个 迭代器对象,里面有 next() 方法,
调用 next()
的结果是一个对象,具有两个属性:
value
: 产出(yielded)的值done
: 如果 generator 函数已执行完成则为 true,否则为 false
迭代器对象的 next 方法的运行逻辑:
- 遇到 yield,将 yield 后面的表达式的值作为返回对象的 value,并暂停执行后面的语句
- 下一次调用 next 方法时,再继续往下执行,直到遇到下一个 yield 表达式
- 继续直到 return 语句为止,并将 return 语句后面的表达式的值,作为返回的对象的 value,同时 done 为 true
- 如果没有 return 语句,则返回的对象的 value 属性值为 undefined
可迭代
因为有符合迭代规则的 next(),所以 generator 是可迭代的,满足可迭代对象的所有用法
如可以使用 for…of 遍历它:
for (let value of g) {
console.log(value) // 1,然后是 2,没有 3
}
注意:没有打印 3,这是因为当 done: true 时,会忽略最后一个 value(其他用法也一样)。因此,如果想要通过 for…of 循环显示所有的结果,必须使用 yield 3 而不是 return 3
NOTE
可迭代用法作用于 generator 时,只会获取 yield 后面的值
yield*
用来在一个 Generator 函数里面执行另一个 Generator 函数
function* g() {
yield* g1()
yield* g2()
yield* g3()
}
next() 传参
next() 可以传参数,将回传赋值给 generator 函数中“上一个” yield 等号前面的变量,也就是作为 yield 语句的返回值
function* gen() {
let res = yield 1
console.log(res)
yield res
}
let g = gen()
g.next()
// 执行后返回 {value: 1, done: false}
g.next(2)
// 执行后打印 2
// 然后返回 {value: 2, done: false}
g.next()
// 执行后返回 {value: undefined, done: true}
用途
用来实现可迭代对象的迭代器(Iterator),将 Generator 赋值给 obj[Symbol.iterator]
,可以使代码更短
如,替换掉 可迭代对象的迭代器:
let range = {
from: 1,
to: 5,
*[Symbol.iterator]() { // [Symbol.iterator]: function*() 的一种简写
for (let value = this.from; value <= this.to; value++) {
yield value
}
}
};
for(let value of range) {
console.log(value) // 1,然后 2,然后 3,然后 4,然后 5
}
异步 Generator
在 function* 前面加上 async,然后使用 for await...of
来遍历它
let range = {
from: 1,
to: 5,
// 这一行等价于 [Symbol.asyncIterator]: async function*() {
async *[Symbol.asyncIterator]() {
for(let value = this.from; value <= this.to; value++) {
// 在 value 之间暂停一会儿,等待一些东西
await new Promise(resolve => setTimeout(resolve, 1000))
yield value
}
}
};
(async () => {
for await (let value of range) {
console.log(value) // 1,然后 2,然后 3,然后 4,然后 5
}
})()
现在,value 之间打印的延迟为 1 秒
Generator 和异步 Generator 之间差异
Generator | 异步 Generator | |
---|---|---|
声明方式 | function* | async function* |
next() 返回值 | {value:..., done: true/false} | resolve 成 {value:..., done: true/false} 的 Promise |