generator-yield到底是个啥

generator-yield到底是个啥
最新回答
醉在街头

2022-02-18 17:28:21

generator-yield是JavaScript中用于实现生成器函数的关键机制,允许函数暂停执行并在后续恢复,同时支持双向参数传递。

一、yield的核心特性
  1. 暂停与恢复执行

    yield会暂停生成器函数的执行,并通过next()方法恢复。

    每次调用next()时,函数会执行到下一个yield或return。

  2. 双向参数传递

    传参给yield:通过next(value)的参数传递给上一个yield的左侧变量。

    function* show() { let a = yield; // 第二个next(5)的参数5会赋给a console.log(a); // 输出5}let gen = show();gen.next(12); // 第一次next()的参数无效gen.next(5); // 传递5给yield

    关键点:第一次next()仅启动生成器,参数被忽略;后续next(value)的参数会成为上一个yield的返回值。

    返回值:yield右侧的表达式会作为next()返回对象的value属性。

    function* show() { yield 12; // 第一次next()返回{value: 12, done: false}}let gen = show();console.log(gen.next()); // {value: 12, done: false}
  3. 与return的区别

    yield返回中间结果(done: false),而return终止函数(done: true)。

    若未显式return,生成器最后返回{value: undefined, done: true}。

二、生成器的工作流程

以“炒菜”伪代码为例:

function* 炒菜(菜市场买回来的) { let 洗好的菜 = yield '洗菜完成'; // 第一次next()返回'洗菜完成' let 切好的菜 = yield '切菜完成'; // 第二次next()返回'切菜完成' return '熟的菜'; // 最终结果}
  • 执行阶段

    调用gen.next()启动生成器,执行到第一个yield,返回{value: '洗菜完成', done: false}。

    调用gen.next('干净的菜'),将'干净的菜'赋给洗好的菜,继续执行到第二个yield,返回{value: '切菜完成', done: false}。

    调用gen.next('切好的菜'),赋值后执行return,返回{value: '熟的菜', done: true}。

三、实际应用场景
  1. 异步控制生成器可与Promise结合,替代回调地狱(类似async/await的底层实现)。

    function* fetchData() { const res1 = yield fetch('url1'); const res2 = yield fetch('url2'); return [res1, res2];}
  2. 惰性计算按需生成序列(如斐波那契数列):

    function* fibonacci() { let [prev, curr] = [0, 1]; while (true) { yield curr; [prev, curr] = [curr, prev + curr]; }}
  3. 状态机通过yield划分不同状态,简化复杂逻辑。

四、注意事项
  • 首次next()的参数无效:生成器启动时未暂停,参数无法传递。
  • 错误处理:可通过gen.throw()向生成器抛出异常。
  • 完成状态:当done: true时,继续调用next()不会重复执行函数。
总结

generator-yield通过暂停/恢复执行和双向参数传递,提供了强大的流程控制能力。其核心在于:

  1. yield分割执行阶段,每个阶段可独立处理输入/输出。
  2. 生成器作为迭代器,通过next()逐步推进。
  3. 与异步编程深度结合,为更高级的抽象(如async/await)奠定基础。

理解这一机制后,可进一步探索其在异步流控制、资源管理等领域的应用。