在这里插入图片描述
在这里插入图片描述

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;
    }
}

Net 中 yield

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐