Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Генератори». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**Функція-генератор** (generator function) - це особливий тип функції в JavaScript, яка може призупиняти своє виконання і потім продовжувати його з того самого місця. **Ключове:** генератор повертає об'єкт-генератор (ітератор) і використовує `yield` для покрокової видачі значень.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення**функція-генератор** (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*` | | Основне застосування | Ліниві обчислення, ітератори, асинхронні потоки |Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.