Генераторы

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

Генераторы - это специальный тип функции, который работает как фабрика итераторов.

Для объявления генератора используется новая синтаксическая конструкция: function* (ключевое слово function со звёздочкой).

function* gen() {
    yield 1;
    yield 2;
    yield 3;
}

const iterator = gen()

Вызов генератора создает объект класса Generator, который является итерируемым (iterable), т. е. его можно перебирать в цикле for..of или просто вызывая метод next(), при этом никакой код внутри генератора пока не выполняется.

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

// 1
console.log(iterator.next())
// [2, 3]
console.log(...iterator)

Передача параметров в метод next

В метод next можно передать значение, которое будет возвращено yield:

Метод throw

У генераторов есть метод throw, который позволяет бросить исключение внутри генератора.

«Вброшенная» в строке (*) ошибка возникает в строке с yield (**). Далее она обрабатывается как обычно. В примере выше она перехватывается try..catch и выводится.

Подробнее:

Метод return

У генераторов есть метод return(value), которое останавливает работу генератора.

Если return(value) вызывает генератор, который находится в уже "завершённом" состоянии, генератор останется в "завершённом" состоянии. Если аргумент не был передан, свойство value вернёт тот же объект, что и .next(). Если аргумент был передан, он будет установлен как значение свойства value возвращаемого объекта.

Подробнее: MDN.

Композиция генераторов

Для генераторов есть особый синтаксис yield*, который позволяет «вкладывать» генераторы один в другой (осуществлять их композицию). Пример:

Примечания

  • Нельзя определить стрелочную функцию генератор, стандартом определен только синтаксис function*

Last updated