Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Yield у генераторах». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**`yield`** - це оператор, який повертає значення з функції-генератора назовні і призупиняє виконання до наступного виклику `.next()`. **Ключове:** коли генератор "доходить" до `yield`, він заморожується, а коли ми знову викликаємо `.next()`, він відновлює роботу одразу після того `yield`, де зупинився.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення## 1. Що робить `yield` > `yield` - це оператор, який **повертає значення** з функції-генератора назовні > і **призупиняє виконання** до наступного виклику `.next()`. Тобто: - коли генератор "доходить" до `yield`, він **заморожується**; - коли ми знову викликаємо `.next()`, він **відновлює роботу** одразу **після** того `yield`, де зупинився. --- ## 2. Найпростіший приклад ```javascript function* gen() { console.log('До першого yield'); yield 1; console.log('Між yield'); yield 2; console.log('Після другого yield'); } const it = gen(); console.log(it.next()); // { value: 1, done: false } console.log(it.next()); // { value: 2, done: false } console.log(it.next()); // { value: undefined, done: true } ``` Що відбувається покроково: 1. `gen()` повертає об'єкт-ітератор -> функція ще не запущена. 2. `it.next()` -> запускає функцію -> доходить до `yield 1`, повертає `{ value: 1 }` і **заморожується**. 3. Наступний `it.next()` -> продовжує з **того самого місця**, після `yield 1`. 4. Після другого `yield` знову "заморожується". 5. Коли `done: true`, генератор завершив роботу. --- ## 3. Як `yield` повертає значення ```javascript function* seq() { yield 'A'; yield 'B'; yield 'C'; } const it = seq(); console.log(it.next().value); // "A" console.log(it.next().value); // "B" console.log(it.next().value); // "C" console.log(it.next().done); // true ``` `yield` - це **"тимчасовий return"**: він повертає значення, але **не завершує функцію**. --- ## 4. Передача значення назад у генератор через `next(value)` `yield` не тільки повертає дані назовні, а й може **приймати значення назад** при наступному виклику `.next(value)`. ```javascript function* dialog() { const name = yield 'Як тебе звати?'; yield `Привіт, ${name}!`; } const chat = dialog(); console.log(chat.next().value); // "Як тебе звати?" console.log(chat.next('Tim').value); // "Привіт, Tim!" ``` - Перший `next()` запустив генератор і дійшов до першого `yield`. - Другий `next('Tim')` передав `'Tim'` у генератор - і це значення потрапило в `const name`. --- ## 5. Завершення генератора через `return` Коли генератор доходить до кінця, або якщо викликати `iterator.return(value)`, він завершує виконання з `done: true`. ```javascript function* numbers() { yield 1; yield 2; } const it = numbers(); console.log(it.next()); // { value: 1, done: false } console.log(it.return('stop')); // { value: 'stop', done: true } console.log(it.next()); // { value: undefined, done: true } ``` --- ## 6. `yield*` - делегування іншому генератору Іноді один генератор може "передати керування" іншому через `yield*`. ```javascript function* inner() { yield 'B'; yield 'C'; } function* outer() { yield 'A'; yield* inner(); // передає керування іншому генератору yield 'D'; } for (const val of outer()) { console.log(val); } ``` Вивід: ```javascript A B C D ``` `yield*` - це **вкладений цикл**: "просто yield усі значення іншого генератора". --- ## 7. Важливий момент - "лінивість" `yield` робить генератори **лінивими (lazy)** - значення обчислюються **тільки за запитом**, а не заздалегідь. ```javascript function* range(start, end) { for (let i = start; i <= end; i++) { console.log('Генерую', i); yield i; } } for (const num of range(1, 3)) { console.log('Отримано:', num); } ``` Вивід: ```javascript Генерую 1 Отримано: 1 Генерую 2 Отримано: 2 Генерую 3 Отримано: 3 ``` Генератор "створює" значення в міру потреби, а не зберігає весь діапазон одразу. --- ## 8. Помилки всередині генератора (`throw`) Можна "закинути" помилку прямо всередину генератора: ```javascript function* gen() { try { yield 1; } catch (e) { console.log('Помилку спіймано:', e.message); } } const it = gen(); it.next(); it.throw(new Error('Щось не так')); // Помилку спіймано: Щось не так ``` --- ## Підсумок | Особливість | Опис | |---|---| | Що робить | Призупиняє виконання і повертає значення | | Відновлення | Через `.next()` | | Чи можна передавати значення назад | Так (`next(value)`) | | Чи можна завершити | Через `return()` | | Чи можна делегувати | Через `yield*` | | Обчислення | Ліниві | | Працює тільки в | `function*` (генераторах) |Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.