> Что такое генераторы в JavaScript и для чего они используются (JavaScript)

Уровень: junior · Роль: frontend · Категория: Технические вопросы

Компании: ООО Премиум ИТ Солюшен

Стек: JavaScript

> Пример ответа

Короткий ответ

Генераторы - это функции, которые могут приостанавливать своё выполнение и возобновлять его позже, сохраняя состояние. Объявляются через function* и используют yield для возврата промежуточных значений. Основное применение - ленивые вычисления, работа с большими данными, создание итераторов, управление асинхронным потоком (например, с помощью co или redux-saga). Генератор возвращает объект-итератор с методами next(), return(), throw().

Подробное объяснение

Генератор - это особый тип функции, которая не выполняется сразу целиком. При вызове она возвращает объект-итератор, а тело функции начинает выполняться только при первом вызове next(). Ключевое отличие от обычной функции - возможность приостановки через yield и последующего возобновления с того же места.

Основные характеристики:

  • function* - синтаксис объявления
  • yield - оператор, который приостанавливает выполнение и возвращает значение
  • next(value) - возобновляет выполнение, при этом value становится результатом выражения yield
  • return(value) - завершает генератор досрочно
  • throw(error) - выбрасывает исключение внутри генератора

Генераторы реализуют протокол итератора, поэтому их можно использовать в for...of, spread-операторе, Array.from() и деструктуризации.

На практике

Генераторы решают несколько практических задач:

  1. Ленивые последовательности - генератор не вычисляет все значения заранее, а выдаёт их по требованию. Это экономит память при работе с большими или бесконечными последовательностями.

  2. Создание итераторов - вместо ручной реализации Symbol.iterator можно использовать генератор, что сильно упрощает код.

  3. Асинхронное программирование - до появления async/await генераторы использовались для написания асинхронного кода в синхронном стиле (например, в redux-saga). Сейчас это менее актуально, но в некоторых библиотеках всё ещё применяется.

  4. Генераторы-делегаты - yield* позволяет делегировать выполнение другому генератору или итерируемому объекту.

Пример кода

JAVASCRIPT
// Простой генератор
function* counter() {
let i = 0;
while (true) {
yield i++;
}
}
const gen = counter();
console.log(gen.next().value); // 0
console.log(gen.next().value); // 1
console.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 (это разные механизмы, хотя исторически связаны)

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью