Что такое генераторы в JavaScript и для чего они используются
Что проверяют
Понимаете ли вы, что функция может приостанавливаться, и связываете ли генераторы с протоколом итерации. Вопрос отделяет знание синтаксиса от понимания: генератор отдаёт значения лениво и умеет принимать их обратно.
Как отвечать
Генератор объявляется через function* и при вызове ничего не выполняет: он возвращает объект, который одновременно итератор и итерируемое. Каждый вызов next() выполняет тело до ближайшего yield и замораживает его вместе со всеми локальными переменными.
function* ids() {
let i = 0;
while (true) yield i++;
}Последовательность бесконечна, но безопасна: значения считаются по требованию. Отсюда применения: ленивые последовательности, постраничный обход, собственный Symbol.iterator у класса, нарезка тяжёлой работы на порции с возвратом управления браузеру.
Обмен идёт в обе стороны. Аргумент next(value) становится результатом того yield, на котором генератор стоял; return() завершает его, а throw() бросает исключение в точку паузы, поэтому блок finally внутри отработает. Делегирование yield* передаёт управление другому генератору.
Про асинхронность стоит сказать честно: сам генератор ничего не ждёт, ожидание появляется, когда его крутит внешний исполнитель. Сегодня эту роль занял async/await, а генераторам остались случаи, где нужен контроль над шагами, плюс асинхронные генераторы с for await для потоков данных.
Где спотыкаются
Называют генератор способом писать асинхронный код и не могут сказать, кто вызывает next(). Без исполнителя, который получает промис и возобновляет генератор его результатом, не происходит ровно ничего.
Забывают, что генератор одноразовый. Дойдя до конца, он навсегда остаётся завершённым, повторный обход даёт пустоту. Поэтому итерируемым делают объект, создающий новый генератор в Symbol.iterator, а не сам генератор.
Путают отдаваемое и возвращаемое значение. То, что ушло через return, попадает в результат с признаком завершения, и обычный обход через for...of его не увидит, как и сборка в массив. На этом регулярно теряют последний элемент.