生成器函数
Generator函数与迭代协议
1. 生成器函数基础
function* simpleGenerator() {
yield 1;
yield 2;
return 3;
}
const gen = simpleGenerator();
console.log(gen.next()); // { value: 1, done: false }
console.log(gen.next()); // { value: 2, done: false }
console.log(gen.next()); // { value: 3, done: true }
1.1 yield 接收值
function* dialog() {
const name = yield '你叫什么名字?';
const age = yield `你好 ${name},你多大了?`;
return `${name},${age}岁`;
}
const it = dialog();
console.log(it.next()); // { value: '你叫什么名字?', done: false }
console.log(it.next('Alice')); // { value: '你好 Alice,你多大了?', done: false }
console.log(it.next(25)); // { value: 'Alice,25岁', done: true }
1.2 yield* 委托
function* inner() {
yield 'a';
yield 'b';
}
function* outer() {
yield 1;
yield* inner();
yield 2;
}
for (const value of outer()) {
console.log(value); // 1, 'a', 'b', 2
}
2. 迭代协议
// 自定义可迭代对象
const range = {
from: 1, to: 5,
[Symbol.iterator]() {
let current = this.from;
return {
next() {
return current <= this.to
? { value: current++, done: false }
: { done: true };
}.bind(this);
}.bind({ to: this.to });
}
};
3. 异步生成器
async function* fetchPages(baseUrl) {
let page = 1;
let hasMore = true;
while (hasMore) {
const response = await fetch(`${baseUrl}?page=${page}`);
const data = await response.json();
yield data.items;
hasMore = data.hasNext;
page++;
}
}
// 消费
async function processAll() {
for await (const items of fetchPages('/api/posts')) {
console.log(items);
}
}
4. 生成器方法
| 方法 | 说明 |
|---|---|
next(value) | 恢复执行 |
return(value) | 终止生成器 |
throw(error) | 在 yield 处抛出错误 |