Дмитрий Нечаев
Генераторы в JavaScript
Генераторы в JavaScript — это особый тип функций, который поддерживает приостановку и возобновление выполнения, при этом сохраняя контекст между последовательными вызовами. Генераторы используются для упрощения работы с асинхронным кодом, обработки потоков данных и реализации пользовательских итераторов. Возвращаемый генератором объект итерируем и поддерживает интерфейс итератора.
Основы генераторов
Генератор объявляется с помощью ключевого слова function*
(звездочка после слова function
). Тело генератора содержит одну или несколько инструкций yield
, которые указывают, на каком месте функция должна быть приостановлена.
function* numberGenerator() {
yield 1;
yield 2;
yield 3;
}
const gen = numberGenerator(); // Создание генератора
console.log(gen.next().value); // 1
console.log(gen.next().value); // 2
console.log(gen.next().value); // 3
console.log(gen.next().value); // undefined, генератор завершил своё выполнение
Методы объекта-генератора
Каждый генератор имеет следующие методы:
- next(): возобновляет выполнение функции до следующей точки
yield
или до конца функции, еслиyield
больше нет. - return(value): прекращает выполнение генератора и возвращает указанное значение.
- throw(error): возобновляет выполнение генератора и передает ошибку внутрь генератора.
function* genFunc() {
try {
yield 1;
yield 2;
} catch(e) {
console.log(e);
}
}
const gen = genFunc();
console.log(gen.next().value); // 1
gen.throw('Произошла ошибка'); // Выведет "Произошла ошибка" и завершит выполнение
Передача значений через yield
Генераторы могут не только возвращать значения, но и получать их через yield
. Это позволяет организовать двустороннюю коммуникацию между генератором и его вызывающим кодом.
function* interactiveGen() {
const input = yield "Введите данные";
yield `Вы ввели: ${input}`;
}
const gen = interactiveGen();
console.log(gen.next().value); // "Введите данные"
console.log(gen.next('Пример данных').value); // "Вы ввели: Пример данных"
Использование генераторов для управления асинхронным кодом
Генераторы могут быть использованы для управления асинхронным кодом, особенно в сочетании с промисами и асинхронными операциями.
function delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
function* asyncFlow() {
console.log('Начало');
yield delay(1000);
console.log('Конец');
}
const gen = asyncFlow();
const promise = gen.next().value; // Начало
promise.then(() => gen.next());
Генераторы для создания итерируемых структур
Генераторы отлично подходят для создания пользовательских итерируемых структур, так как они позволяют легко определять логику перебора.
function* range(start, end) {
for (let i = start; i <= end; i++) {
yield i;
}
}
const r = range(1, 5);
for (const num of r) {
console.log(num); // Выведет числа от 1 до 5
}
Заключение
Генераторы в JavaScript — это мощный инструмент для создания функций, которые можно приостанавливать и возобновлять, что особенно полезно для управления асинхронными операциями и создания итерируемых структур. Благодаря своей гибкости и возможности взаимодействия с вызывающим кодом, генераторы открывают широкие возможности для реализации сложной логики в вашем JavaScript-коде.
Карта развития разработчика
Получите полную карту развития разработчика по всем направлениям: frontend, backend, devops, mobile