js 实现generator
Generator 实现基础
Generator 是 ES6 引入的一种特殊函数,通过 function* 语法定义,内部使用 yield 关键字暂停执行并返回中间值。Generator 函数调用时返回一个迭代器对象,通过调用 next() 方法逐步执行。
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 }
生成无限序列
Generator 可以用于生成无限序列,例如斐波那契数列。由于惰性求值特性,只有在调用 next() 时才会计算下一个值。
function* fibonacci() {
let [prev, curr] = [0, 1];
while (true) {
yield curr;
[prev, curr] = [curr, prev + curr];
}
}
const fib = fibonacci();
console.log(fib.next().value); // 1
console.log(fib.next().value); // 1
console.log(fib.next().value); // 2
异步流程控制
Generator 结合 Promise 可以实现类似 async/await 的异步流程控制。通过 yield 暂停执行,等待 Promise 解析后再继续。

function* asyncTask() {
const result1 = yield fetch('https://api.example.com/data1');
const result2 = yield fetch('https://api.example.com/data2');
return [result1, result2];
}
function runGenerator(gen) {
const iterator = gen();
function handle(result) {
if (result.done) return result.value;
return Promise.resolve(result.value).then(res => {
return handle(iterator.next(res));
});
}
return handle(iterator.next());
}
runGenerator(asyncTask).then(results => console.log(results));
错误处理
Generator 内部可以通过 try/catch 捕获错误,外部也可以通过 iterator.throw() 方法抛出错误。
function* errorHandling() {
try {
yield 1;
throw new Error('Generator error');
} catch (e) {
console.log('Caught inside:', e.message);
}
}
const gen = errorHandling();
gen.next(); // { value: 1, done: false }
gen.throw(new Error('External error')); // Caught inside: External error
与迭代器协议结合
Generator 对象天然实现了迭代器协议,可以直接用于 for...of 循环或解构赋值。

function* range(start, end) {
for (let i = start; i <= end; i++) {
yield i;
}
}
for (const num of range(1, 5)) {
console.log(num); // 1, 2, 3, 4, 5
}
const [a, b] = range(1, 2);
console.log(a, b); // 1 2
yield* 委托
yield* 表达式用于委托给另一个 Generator 或可迭代对象,简化嵌套 Generator 的调用。
function* generatorA() {
yield 'a';
yield 'b';
}
function* generatorB() {
yield* generatorA();
yield 'c';
}
console.log([...generatorB()]); // ['a', 'b', 'c']
状态机应用
Generator 可以用于实现状态机,通过 yield 暂停在不同状态,通过 next() 触发状态转换。
function* trafficLight() {
while (true) {
yield 'red';
yield 'yellow';
yield 'green';
}
}
const light = trafficLight();
console.log(light.next().value); // 'red'
console.log(light.next().value); // 'yellow'
console.log(light.next().value); // 'green'






