Что такое генераторы в JavaScript?
Генераторы — это функции, которые могут приостанавливать своё выполнение и возобновлять его позже. Они дают больше контроля над потоком выполнения, в отличие от обычных функций.
Генераторы определяются с помощью function*
и управляются через метод .next()
.
Синтаксис генератора
function* generatorFunction() {
yield 'Первое значение';
yield 'Второе значение';
return 'Финал';
}
const gen = generatorFunction();
console.log(gen.next()); // { value: 'Первое значение', done: false }
console.log(gen.next()); // { value: 'Второе значение', done: false }
console.log(gen.next()); // { value: 'Финал', done: true }
Как работает генератор
yield
— ключевое слово, приостанавливает выполнение и возвращает значение..next()
— возобновляет выполнение с места последнегоyield
.done: true
— указывает, что генератор завершён.
Отличия от обычных функций
Особенность | Обычные функции | Генераторы |
---|---|---|
Возврат значений | Только один return | Много yield |
Промежуточные состояния | Нет | Да |
Управление потоком | Нет | Да |
Использование for..of | Нет | Да |
Генераторы и итераторы
Генератор — это итератор, соответствующий протоколу Iterable. Это позволяет использовать его в цикле for...of
.
function* range(start, end) {
for (let i = start; i <= end; i++) {
yield i;
}
}
for (const num of range(1, 5)) {
console.log(num); // 1, 2, 3, 4, 5
}
Когда использовать генераторы?
Полезны для:
- Работы с потоками данных — например, генерация последовательностей.
- Итерируемых структур — массивы, деревья, графы.
- Контроля за выполнением — например, когда нужно вручную пошагово обрабатывать данные.
- Создания ленивых вычислений (lazy evaluation).
- Имитации async-поведения до появления
async/await
.
Пример: Генератор бесконечной последовательности
function* infiniteCounter() {
let i = 0;
while (true) {
yield i++;
}
}
const counter = infiniteCounter();
console.log(counter.next().value); // 0
console.log(counter.next().value); // 1
console.log(counter.next().value); // 2
Вывод:
Генераторы — мощный инструмент для создания итераторов, управления асинхронным потоком и ленивой генерации данных. Используйте их, когда нужно больше контроля над выполнением кода.