Generators: yield, next(), return()
Генераторы: магия, которая делает итераторы простыми ✨
Генераторы — это особый вид функций в JavaScript, умеющих ставить на паузу своё выполнение и возобновлять его по требованию. В отличие от обычных функций (которые работают «от и до»), генераторы выдают значения по одному, как конвейер.
function* simpleGenerator() {
yield 1;
yield 2;
return 3;
}
🔍 Ключевой момент: звёздочка (
*) послеfunction— это не просто синтаксис. Она говорит движку: «Эта функция — особенная, запомни её».
Как работают yield и next()
Генератор не выполняется сразу при вызове. Вместо этого он возвращает объект-итератор с методами:
next()— запускает выполнение до ближайшегоyieldилиreturnreturn()— принудительно завершает генераторthrow()— вызывает ошибку внутри генератора (но это уже продвинутая тема)
const gen = simpleGenerator();
console.log(gen.next()); // { value: 1, done: false }
console.log(gen.next()); // { value: 2, done: false }
console.log(gen.next()); // { value: 3, done: true }
Жизненный цикл генератора в деталях
-
Создание
Генератор «замораживается» на старте. Код не выполняется. -
Первый
next()
Движок доходит до первогоyield, возвращает его значение и засыпает. -
Следующие вызовы
Продолжает с места остановки до новогоyieldилиreturn. -
Завершение
Послеreturnили последнегоyieldсвойствоdoneстановитсяtrue.
Пример: Бесконечная последовательность
Генераторы идеальны для работы с бесконечными данными — они вычисляют значения лениво (по запросу):
function* idGenerator() {
let id = 0;
while (true) {
yield id++;
}
}
const userIds = idGenerator();
console.log(userIds.next().value); // 0
console.log(userIds.next().value); // 1
// Можно вызывать бесконечно!
💡 Совет: такой подход экономит память — не нужно хранить весь массив ID.
Метод return(): аварийное завершение
Что, если нужно прервать генератор досрочно? Метод return() сделает это:
function* weatherControl() {
yield '☀️ Солнечно';
yield '🌧️ Дождь';
yield '❄️ Снег';
}
const weather = weatherControl();
console.log(weather.next().value); // '☀️ Солнечно'
console.log(weather.return('🌀 Ураган')); // { value: '🌀 Ураган', done: true }
console.log(weather.next()); // { value: undefined, done: true }
После return() генератор переходит в состояние done: true и больше не работает.
Практика: Генератор случайных чисел с лимитом
Создадим генератор, который выдаёт случайные числа, но останавливается при превышении лимита:
function* randomGenerator(limit) {
while (true) {
const num = Math.floor(Math.random() * 10);
if (num > limit) return 'Лимит превышен!'; // Выход
yield num;
}
}
const randomizer = randomGenerator(7);
console.log(randomizer.next()); // Например, { value: 3, done: false }
console.log(randomizer.next()); // { value: 7, done: false }
console.log(randomizer.next()); // Может вернуть { value: 'Лимит превышен!', done: true }
Где это применяется в реальности?
- Ленивые вычисления — данные обрабатываются только когда нужны.
- Асинхронные операции — вместе с
async/await(но это отдельная история). - Работа с деревьями — обход сложных структур данных.
- Redux-Saga — популярная библиотека для управления побочными эффектами.
Если хотите глубже разобрать асинхронные генераторы — посмотрите разборы Данилы Бежина на YouTube.
Итоговый чек-лист
- Генераторы создаются через
function*. yield— ключевое слово для паузы.next()— возобновляет выполнение.return()— экстренная остановка.- Идеальны для обработки потоков данных.
Теперь вы умеете работать с одной из самых мощных возможностей JavaScript! 🚀