ES6>>JavaScript 中的 Generator(生成器) async/await
·



Generator 作为可迭代对象
由于 Generator 对象实现了迭代器协议,我们可以用 for…of 循环来遍历它。需要注意的是,for…of 循环不会处理 done 为 true 时对应的 value(即 return 的返回值)。
function* numberGenerator() {
yield 1;
yield 2;
yield 3;
return 4; // for...of 会忽略这个值
}
const gen = numberGenerator();
for (let value of gen) {
console.log(value);
}
// 输出:
// 1
// 2
// 3
双向通信:向 next() 传递参数
.next() 方法可以接受一个参数,这个参数会作为上一个 yield 表达式在函数内部恢复执行时的返回值。这是 Generator 一个非常强大的特性。
function* twoWayGenerator() {
const name = yield 'Please tell me your name.'; // 第一次 next() 停在这里,返回 'Please tell me...'
yield `Hello, ${name}!`; // 第二次 next('Alice') 将 'Alice' 赋值给 name,然后停在这里
}
const gen = twoWayGenerator();
console.log(gen.next().value); // 输出:Please tell me your name.
console.log(gen.next('Alice').value); // 输出:Hello, Alice!
委托 yield (yield*)
yield* 用于在一个 Generator 函数中“调用”另一个 Generator 函数,相当于将其执行过程“委托”出去。
function* generatorA() {
yield 'A1';
yield 'A2';
}
function* generatorB() {
yield 'B1';
yield* generatorA(); // 委托给 generatorA
yield 'B2';
}
const gen = generatorB();
for (let value of gen) {
console.log(value);
}
// 输出:
// B1
// A1
// A2
// B2
现在 推荐 async/await,但 Generator 所提供的惰性求值和控制权交出的能力,使其在特定场景下依然非常有用








.NET 中 yield 语法糖
在 .NET 中,yield 关键字用于实现迭代器方法,它简化了迭代器模式的实现。使用 yield 的方法会在幕后由编译器自动生成一个状态机。
# 基本语法
public IEnumerable<T> MethodName( 可以传参)
{
// ...
yield return value; // 产生一个值
// ...
yield break; // 提前终止迭代
}
using System;
using System.Collections.Generic;
public class Program
{
public static IEnumerable<int> GetNumbers()
{
Console.WriteLine("开始执行");
yield return 1;
Console.WriteLine("产生了 1");
yield return 2;
Console.WriteLine("产生了 2");
yield return 3;
Console.WriteLine("产生了 3");
}
public static void Main()
{
// js中 用 for of
foreach (var number in GetNumbers())
{
Console.WriteLine($"获取: {number}");
}
// 输出:
// 开始执行
// 获取: 1
// 产生了 1
// 获取: 2
// 产生了 2
// 获取: 3
// 产生了 3
}
}
public static IEnumerable<int> GetNumbersUntilNegative(IEnumerable<int> numbers)
{
foreach (var num in numbers)
{
if (num < 0)
yield break; // 遇到负数就停止
yield return num;
}
}
更多推荐


所有评论(0)