Генераторы¶
function * - это синтаксис, используемый для создания функции генератора. Вызов функции генератора возвращает объект генератора. Объект генератора просто реализует интерфейс iterator (а именно функции next, return и throw).
Существуют 2 основные причины использовать функции генератора:
Ленивые итераторы¶
Функции генератора могут использоваться для создания ленивых итераторов, например, следующая функция возвращает бесконечный список целых чисел по запросу:
1 2 3 4 5 6 7 8 9 10 11 | |
Конечно, если итератор завершится, вы получите результат {done: true}, как показано ниже:
1 2 3 4 5 6 7 8 9 10 11 | |
Внешнее контролируемое исполнение¶
Это та роль генераторов, которая действительно восхищает. По сути, это позволяет функции приостановить выполнение и передать управление оставшейся части функции вызывающей стороне.
Функция генератора не выполняется при вызове. Она просто создает объект генератора. Рассмотрим следующий пример вместе с примером выполнения:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | |
Если вы запустите это, вы получите следующий вывод:
1 2 3 4 5 6 7 8 | |
- Функция начинает выполнение только после вызова
nextобъекта-генератора. - Функция делает паузу, как только встречается оператор yield.
- Функция возобновляется при вызове
next.
Так что, по сути, выполнение функции генератора контролируется объектом генератора.
Наше общение с использованием генератора было в основном односторонним, когда генератор возвращал значения для итератора. Одна чрезвычайно мощная особенность генераторов в JavaScript состоит в том, что они допускают двустороннюю связь!
- Вы можете контролировать результирующее значение выражения
yield, используяiterator.next(valueToInject) - вы можете бросить исключение в выражении
yield, используяiterator.throw(error)
В следующем примере демонстрируется iterator.next(valueToInject):
1 2 3 4 5 6 7 8 9 10 11 | |
В следующем примере демонстрируется iterator.throw(error):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | |
Итак, вот резюме:
yieldпозволяет функции генератора приостанавливать выполнение и передавать управление внешней системе- внешняя система может передать значение в тело функции генератора
- внешняя система может бросить исключение в тело функции генератора
И чем это может быть полезно? Перейдите к следующему разделу async/await и узнайте.