> Что такое генераторы в JavaScript и для чего они используются (JavaScript)
Уровень: junior · Роль: frontend · Категория: Технические вопросы
Компании: ООО Премиум ИТ Солюшен
Стек: JavaScript
> Пример ответа
Короткий ответ
Генераторы - это функции, которые могут приостанавливать своё выполнение и возобновлять его позже, сохраняя состояние. Объявляются через function* и используют yield для возврата промежуточных значений. Основное применение - ленивые вычисления, работа с большими данными, создание итераторов, управление асинхронным потоком (например, с помощью co или redux-saga). Генератор возвращает объект-итератор с методами next(), return(), throw().
Подробное объяснение
Генератор - это особый тип функции, которая не выполняется сразу целиком. При вызове она возвращает объект-итератор, а тело функции начинает выполняться только при первом вызове next(). Ключевое отличие от обычной функции - возможность приостановки через yield и последующего возобновления с того же места.
Основные характеристики:
function*- синтаксис объявленияyield- оператор, который приостанавливает выполнение и возвращает значениеnext(value)- возобновляет выполнение, при этомvalueстановится результатом выраженияyieldreturn(value)- завершает генератор досрочноthrow(error)- выбрасывает исключение внутри генератора
Генераторы реализуют протокол итератора, поэтому их можно использовать в for...of, spread-операторе, Array.from() и деструктуризации.
На практике
Генераторы решают несколько практических задач:
-
Ленивые последовательности - генератор не вычисляет все значения заранее, а выдаёт их по требованию. Это экономит память при работе с большими или бесконечными последовательностями.
-
Создание итераторов - вместо ручной реализации
Symbol.iteratorможно использовать генератор, что сильно упрощает код. -
Асинхронное программирование - до появления
async/awaitгенераторы использовались для написания асинхронного кода в синхронном стиле (например, вredux-saga). Сейчас это менее актуально, но в некоторых библиотеках всё ещё применяется. -
Генераторы-делегаты -
yield*позволяет делегировать выполнение другому генератору или итерируемому объекту.
Пример кода
JAVASCRIPT// Простой генераторfunction* counter() {let i = 0;while (true) {yield i++;}}const gen = counter();console.log(gen.next().value); // 0console.log(gen.next().value); // 1console.log(gen.next().value); // 2// Генератор как итератор для объектаconst obj = {values: [10, 20, 30],*[Symbol.iterator]() {for (const v of this.values) {yield v;}}};for (const item of obj) {console.log(item); // 10, 20, 30}// Передача значения в генератор через next()function* talk() {const name = yield "Как тебя зовут?";const age = yield `Привет, ${name}! Сколько тебе лет?`;return `${name}, тебе ${age} лет.`;}const dialog = talk();console.log(dialog.next().value); // "Как тебя зовут?"console.log(dialog.next("Анна").value); // "Привет, Анна! Сколько тебе лет?"console.log(dialog.next(25).value); // "Анна, тебе 25 лет."// Делегирование через yield*function* inner() {yield 1;yield 2;}function* outer() {yield 0;yield* inner();yield 3;}console.log([...outer()]); // [0, 1, 2, 3]
Как отвечать на собеседовании
Начни с краткого определения, затем покажи синтаксис на простом примере. Объясни, чем генератор отличается от обычной функции: приостановка и возобновление, сохранение состояния. Упомяни протокол итератора и yield*. Расскажи про практическое применение: ленивые вычисления, работа с бесконечными последовательностями, асинхронный код (исторически). Если спросят про async/await - скажи, что это синтаксический сахар над промисами, а генераторы - более низкоуровневый механизм.
Что проверяет интервьюер
Интервьюер проверяет:
- понимание разницы между обычной функцией и генератором
- знание синтаксиса:
function*,yield,next() - понимание ленивых вычислений и экономии памяти
- умение объяснить, как работает передача значения через
next() - знание
yield*и делегирования - понимание связи генераторов с итераторами
Типичные ошибки
- путать
yieldиreturn-returnзавершает генератор, аyieldприостанавливает - забывать, что генератор возвращает итератор, а не выполняет тело сразу
- использовать генератор там, где достаточно обычной функции или массива
- не понимать, что
next(value)передаёт значение в генератор, а не просто возобновляет его - считать, что генераторы - это то же самое, что
async/await(это разные механизмы, хотя исторически связаны)
> Похожие задачи по frontend
Как положить результат промиса в массив по индексу в JavaScript?
Вернёт ли метод map в JavaScript новый массив с новыми объектами или с теми же старыми объектами при добавлении свойства к объектам?
Какие значения являются falsy в JavaScript
Когда в JavaScript проверяются типы?
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью