yield

Baseline 已广泛支持

此特性已非常成熟,可在多种设备和浏览器版本上使用。自 ⁨2016 年 9 月⁩以来,它已在各大浏览器中可用。

yield 操作符用于暂停和恢复生成器函数的执行。

试一试

function* foo(index) {
  while (index < 2) {
    yield index;
    index++;
  }
}

const iterator = foo(0);

console.log(iterator.next().value);
// Expected output: 0

console.log(iterator.next().value);
// Expected output: 1

语法

js
yield
yield expression

参数

expression 可选

通过迭代器协议从生成器函数中产出的值。如果省略,则产出 undefined

返回值

返回传递给生成器的 next() 方法以恢复其执行的可选值。

注意:这意味着 next() 是不对称的:它总是向当前暂停的 yield 发送一个值,但返回下一个 yield 的操作数。传递给第一次 next() 调用的参数无法检索,因为没有当前暂停的 yield

描述

yield 关键字暂停生成器函数的执行,并且 yield 关键字后的表达式的值将返回给生成器的调用者。可以将其视为基于生成器版本的 return 关键字。

yield 只能直接在其包含的生成器函数中使用。它不能在嵌套函数中使用。

调用生成器函数会构造一个Generator 对象。每次调用生成器的next() 方法时,生成器都会恢复执行,并运行直到达到以下条件之一:

  • 一个 yield 表达式。在这种情况下,生成器暂停,并且 next() 方法返回一个具有两个属性的迭代器结果对象:valuedonevalue 属性是 yield 操作符之后表达式的值,donefalse,表示生成器函数尚未完全完成。
  • 生成器函数的末尾。在这种情况下,生成器的执行结束,并且 next() 方法返回一个迭代器结果对象,其中 valueundefineddonetrue
  • 一个 return 语句。在这种情况下,生成器的执行结束,并且 next() 方法返回一个迭代器结果对象,其中 value 为指定的返回值,donetrue
  • 一个 throw 语句。在这种情况下,生成器的执行完全停止,并且 next() 方法抛出指定的异常。

一旦在 yield 表达式处暂停,生成器的代码执行将保持暂停状态,直到再次调用生成器的 next() 方法。如果将可选值传递给生成器的 next() 方法,则该值将成为生成器当前 yield 操作返回的值。第一次 next() 调用没有相应的暂停 yield 操作,因此无法获取传递给第一次 next() 调用的参数。

如果调用了生成器的return()throw() 方法,其作用类似于在暂停的 yield 表达式处执行了 returnthrow 语句。您可以在生成器函数体中使用 try...catch...finally 来处理这些提前完成。如果调用 return()throw() 方法但没有暂停的 yield 表达式(因为 next() 尚未被调用,或者因为生成器已经完成),那么这些提前完成将无法处理,并且总是终止生成器。

示例

使用 yield

以下代码是一个示例生成器函数的声明。

js
function* countAppleSales() {
  const saleList = [3, 7, 5];
  for (const sale of saleList) {
    yield sale;
  }
}

一旦定义了生成器函数,就可以通过构造迭代器来使用它,如所示。

js
const appleStore = countAppleSales(); // Generator { }
console.log(appleStore.next()); // { value: 3, done: false }
console.log(appleStore.next()); // { value: 7, done: false }
console.log(appleStore.next()); // { value: 5, done: false }
console.log(appleStore.next()); // { value: undefined, done: true }

您还可以使用 next(value) 将一个值发送到生成器中。step 将作为 yield 表达式的返回值进行评估——尽管第一次调用 next() 时传递给生成器 next() 方法的值会被忽略。

js
function* counter(value) {
  while (true) {
    const step = yield value++;

    if (step) {
      value += step;
    }
  }
}

const generatorFunc = counter(0);
console.log(generatorFunc.next().value); // 0
console.log(generatorFunc.next().value); // 1
console.log(generatorFunc.next().value); // 2
console.log(generatorFunc.next().value); // 3
console.log(generatorFunc.next(10).value); // 14
console.log(generatorFunc.next().value); // 15
console.log(generatorFunc.next(10).value); // 26

规范

规范
ECMAScript® 2026 语言规范
# prod-YieldExpression

浏览器兼容性

另见