Files
2025-03-25 16:40:25 +03:00

4.7 KiB
Raw Permalink Blame History

sidebar_position
sidebar_position
1

Генераторы

Обычные функции возвращают только одно-единственное значение (или ничего).

Генераторы могут порождать (yield) множество значений одно за другим, по мере необходимости. Генераторы отлично работают с перебираемыми объектами и позволяют легко создавать потоки данных.

  • Генераторы создаются при помощи функций-генераторов function* f(…) {…}.
  • Внутри генераторов и только внутри них существует оператор yield.
  • Внешний код и генератор обмениваются промежуточными результатами посредством вызовов next/yield.

В современном JavaScript генераторы используются редко. Но иногда они оказываются полезными, потому что способность функции обмениваться данными с вызывающим кодом во время выполнения совершенно уникальна. И, конечно, для создания перебираемых объектов.

Функция-генератор

Источник: https://learn.javascript.ru/generators Для объявления генератора используется специальная синтаксическая конструкция: function*, которая называется «функция-генератор».

Основным методом генератора является next(). При вызове он запускает выполнение кода до ближайшей инструкции yield <значение> (значение может отсутствовать, в этом случае оно предполагается равным undefined). По достижении yield выполнение функции приостанавливается, а соответствующее значение возвращается во внешний код:

Результатом метода next() всегда является объект с двумя свойствами:

  • value: значение из yield.
  • done: true, если выполнение функции завершено, иначе false.
function* generateSequence() {
  yield 1;
  yield 2;
  return 3;
}
let generator = generateSequence();
let one = generator.next();
alert(JSON.stringify(one)); // {value: 1, done: false}

💥 function* f(…) или function *f(…)

Нет разницы, оба синтаксиса корректны.
Но обычно предпочтителен первый вариант, так как звёздочка относится к типу объявляемой сущности (function* «функция-генератор»), а не к её названию, так что резонно расположить её у слова function.

Перебор генераторов

Как вы, наверное, уже догадались по наличию метода next(), генераторы являются перебираемыми объектами.

Возвращаемые ими значения можно перебирать через for..of Это из-за того, что перебор через for..of игнорирует последнее значение, при котором done: true. Поэтому, если мы хотим, чтобы были все значения при переборе через for..of, то надо возвращать их через yield:

function* generateSequence() {
  yield 1;
  yield 2;
  yield 3;
}
let generator = generateSequence();
for(let value of generator) {
  alert(value); // 1, затем 2, затем 3
}

yield дорога в обе стороны

yield дорога в обе стороны: он не только возвращает результат наружу, но и может передавать значение извне в генератор.

Чтобы это сделать, нам нужно вызвать generator.next(arg) с аргументом. Этот аргумент становится результатом yield.

🚀 Источник: https://learn.javascript.ru/generators