yield

Ключове слово yield використовується для призупинення та відновлення виконання функції-генератора (function* або застарілої функції-генератора).

Синтаксис

[rv] = yield [expression];
expression
Визначає значення, яке буде повернене функцією-генератором згідно протоколу ітератора. Якщо пропущене, повертається undefined.
rv

Отримує необов'язкове значення, передане у метод генератора next() для відновлення виконання.

Опис

Ключове слово yield призупиняє виконання функції-генератора, а значення виразу, що стоїть після yield, повертається у інструкцію, що викликала генератор. Його можна уявити як генераторну версію ключового слова return.

Оператор yield може викликатись тільки безпосередньо з функції-генератора, яка його містить. Його не можна викликати з вкладених функцій або зворотних викликів.

Ключове слово yield здійснює виклик метода генератора next(), повертаючи об'єкт IteratorResult з двома властивостями, value та done. Властивість value є результатом обчислення виразу yield, а done дорівнює false, вказуючи, що функція-генератор ще не завершена.

Зупинившись на виразі yield, виконання коду генератора залишається на паузі до виклику методу генератора next(). Кожний раз, коли викликається метод генератора next(), генератор відновлює виконання та виконується, поки не досягає чогось з наступного:

  • Ключове слово yield, яке змушує генератор знову призупинитись та повертає нове значення генератора. Наступний раз, коли викликатиметься next(), виконання продовжиться з інструкції, що стоїть одразу після yield.
  • Оператор throw використовується для викидання винятків у генераторі. Він повністю зупиняє виконання генератора, а виконання коду продовжується у місці виклику, як це стандартно відбувається, коли викидається виняток.
  • Досягнуто кінця функції-генератора; у цьому випадку виконання генератора завершується, а IteratorResult повертається з value, що дорівнює undefined, та done, що дорівнює true.
  • Досягнуто оператора return. У цьому випадку виконання генератора завершується, а IteratorResult повертається з value, що дорівнює значенню, вказаному у return, та done, що дорівнює true.

Якщо у метод генератора next() було передано необов'язкове значення, воно стає значенням, що повертається поточною операцією генератора yield.

Маючи фрагменти коду, що виконуються генератором, оператори yield та здатність вказувати нове початкове значення, передаючи його у Generator.prototype.next(), генератори надають неймовірну потужність та контроль.

Приклади

Наступний код є оголошенням прикладу функції-генератора.

function* countAppleSales () {
  var saleList = [3, 7, 5];
  for (var i = 0; i < saleList.length; i++) {
    yield saleList[i];
  }
}

Як тільки функція-генератор визначена, її можна використовувати, створивши ітератор, як показано нижче.

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

Специфікації

Специфікація Статус Коментар
ECMAScript 2015 (6th Edition, ECMA-262)
The definition of 'Yield' in that specification.
Standard Початкове визначення.
ECMAScript (ECMA-262)
The definition of 'Yield' in that specification.
Living Standard

Сумісність з веб-переглядачами

BCD tables only load in the browser

Примітки щодо Firefox

  • Починаючи з Gecko 29 (Firefox 29 / Thunderbird 29 / SeaMonkey 2.26), завершена функція-генератор більше не викидає помилку TypeError "generator has already finished". Замість цього вона повертає об'єкт IteratorResult у вигляді { value: undefined, done: true } (bug 958951).
  • Починаючи з Gecko 33 (Firefox 33 / Thunderbird 33 / SeaMonkey 2.30) розбір виразу yield було оновлено для відповідності специфікації ES2015 (bug 981599):
    • Вираз після ключового слова yield є необов'язковим, і  його пропуск більше не викидає помилку SyntaxError: function* countAppleSales() { yield; }

Див. також