логотип PurpleSchool
логотип PurpleSchool

Генераторы в 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-коде.

Стрелочка влевоIntl.DateTimeFormat в JavaScriptДескрипторы в JavaScriptСтрелочка вправо

Все гайды по Javascript

Как работает метод trim() - JavaScriptКак работает метод toUpperCase() - JavaScriptКак работает метод toLowerCase() - JavaScriptКак работает метод substring() - JavaScriptКак работает метод startsWith() - JavaScriptКак работает метод split() - JavaScriptКак работает метод slice() - JavaScriptКак работает метод search() - JavaScriptКак работает метод replaceAll() - JavaScriptКак работает метод replace() - JavaScriptКак работает метод repeat() - JavaScriptКак работает метод padStart() - JavaScriptКак работает метод padEnd() - JavaScriptКак работает метод matchAll() - JavaScriptКак работает метод match() - JavaScriptКак работает метод localeCompare() - JavaScriptКак работает свойство length - JavaScriptКак работает метод lastIndexOf() - JavaScriptКак работает метод indexOf() - JavaScriptКак работает метод includes() - JavaScriptКак работает метод fromCodePoint() - JavaScriptКак работает метод fromCharCode() - JavaScriptКак работает метод endsWith() - JavaScriptКак работает метод concat() - JavaScriptКак работает метод codePointAt() - JavaScriptКак работает метод charCodeAt() - JavaScriptКак работает метод charAt() - JavaScript
Итератор в JavaScript
Error в JavaScripttry...catch в JavaScript
Событие wheel в JavaScriptСобытие unload в JavaScriptСобытие touch в JavaScriptСобытие submit в JavaScriptСобытие scroll в JavaScriptСобытие reset в JavaScriptМетод .preventDefault() в JavaScriptСобытие mouseover в JavaScriptСобытие mouseout в JavaScriptСобытие load в JavaScriptСобытие keyup в JavaScriptСобытие keydown в JavaScriptСобытие invalid в JavaScriptСобытие input в JavaScriptСобытийная модель Event в JavaScriptОбъект события Event в JavaScriptСобытие DOMContentLoaded в JavaScriptСобытие dblclick в JavaScriptСобытие click в JavaScriptСобытие change в JavaScriptСобытие beforeunload в JavaScript
Как работает метод some() - JavaScriptКак работает метод reverse() - JavaScriptКак работает метод reduce() - JavaScriptКак работает метод map() - JavaScriptКак работает метод isArray() - JavaScriptКак работает метод indexOf() - JavaScriptКак работает метод includes() - JavaScriptКак работает метод from() - JavaScriptКак работает метод forEach() - JavaScriptКак работает метод flatMap() - JavaScriptКак работает метод flat() - JavaScriptКак работает метод findIndex() - JavaScriptКак работает метод find() - JavaScriptКак работает метод filter() - JavaScriptКак работает метод every() - JavaScriptМассивы в JavaScript
Открыть базу знаний