Skip to main content

Генератори

функція-генератор (generator function) - це особливий тип функції в JavaScript, яка може призупиняти своє виконання і потім продовжувати його з того самого місця.

Це дуже потужний інструмент - вона дозволяє писати ітератори, ліниві обчислення, асинхронні цикли і багато іншого. Розберемося по кроках.


1. Визначення

Функція-генератор - це функція, яка повертає об'єкт-генератор (ітератор), а всередині себе використовує ключове слово yield, щоб призупиняти виконання і повертати значення по одному.


2. Синтаксис

javascript
function* name([args]) { // тіло функції }
  • * після function робить функцію генератором;
  • yield використовується для "покрокової" видачі значень;
  • при виклику вона не виконується одразу, а повертає генератор (ітератор).

3. Приклад - базовий генератор

javascript
function* gen() { yield 1; yield 2; yield 3; } const iterator = gen(); console.log(iterator.next()); // { value: 1, done: false } console.log(iterator.next()); // { value: 2, done: false } console.log(iterator.next()); // { value: 3, done: false } console.log(iterator.next()); // { value: undefined, done: true }

Що відбувається:

  • при першому виклику next() - виконання доходить до першого yield, повертає 1 і "замерзає";
  • при наступному next() виконання продовжується з того самого місця;
  • після останнього yield генератор завершує роботу (done: true).

4. Генератори - це ітератори

Генератор повертає об'єкт, сумісний із протоколом ітераторів. Отже, його можна використовувати в for...of:

javascript
function* numbers() { yield 10; yield 20; yield 30; } for (const n of numbers()) { console.log(n); }

Вивід:

javascript
10 20 30

5. Приклад - нескінченний генератор

Генератори можуть бути нескінченними - вони не створюють весь масив одразу, а видають значення "за запитом".

javascript
function* infiniteCounter() { let i = 1; while (true) { yield i++; } } const counter = infiniteCounter(); console.log(counter.next().value); // 1 console.log(counter.next().value); // 2 console.log(counter.next().value); // 3 // ...і так нескінченно

Це приклад лінивих обчислень - значення генеруються в міру необхідності.


6. Передача значень у генератор

Можна передавати дані назад у генератор через next(value).

javascript
function* dialog() { const name = yield 'Як тебе звати?'; yield `Привіт, ${name}!`; } const it = dialog(); console.log(it.next().value); // "Як тебе звати?" console.log(it.next('Тим').value); // "Привіт, Тим!"

Перший next() запускає генератор, другий - передає 'Тим' всередину як результат виразу yield.


7. Використання з return

Можна завершити генератор раніше за допомогою return:

javascript
function* example() { yield 1; return 'кінець'; yield 2; // не виконається } const it = example(); console.log(it.next()); // { value: 1, done: false } console.log(it.next()); // { value: 'кінець', done: true }

8. Асинхронні генератори (ES2018)

Асинхронні генератори дозволяють працювати з await всередині ітерованих потоків даних.

javascript
async function* fetchData() { yield await Promise.resolve('Перша частина'); yield await Promise.resolve('Друга частина'); } for await (const part of fetchData()) { console.log(part); }

Асинхронні генератори використовують for await...of для асинхронного обходу.


9. Навіщо потрібні генератори

ЗастосуванняПриклад
Створення ітераторівПоелементна генерація даних
Ліниві обчисленняНе потрібно зберігати масив цілком
Покрокове виконанняКерування потоком виконання
Асинхронні пайплайниОбробка потоків даних без завантаження пам'яті
Емуляція корутинМожливість "зупинити" і "продовжити" код

10. Приклад - генератор діапазону

javascript
function* range(start, end, step = 1) { for (let i = start; i <= end; i += step) { yield i; } } for (const num of range(1, 5)) { console.log(num); }

Вивід:

javascript
1 2 3 4 5

ПІДСУМОК

ВластивістьОпис
ВизначенняФункція з function*, що повертає ітератор
ПовертаєОб'єкт генератора
Ключове словоyield
Можна призупиняти виконанняТак
Можна передавати значення назадТак
Асинхронна версіяasync function*
Основне застосуванняЛіниві обчислення, ітератори, асинхронні потоки

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.