Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Мікро- проти макрозадач». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**Мікрозадачі і макрозадачі це дві різні черги, які Event Loop обробляє в різний час: макрозадачі це «великі» події (таймери, мережеві запити, події DOM), а мікрозадачі це «миттєві» задачі, що виконуються одразу після поточного коду, але до наступної макрозадачі.** За один оберт циклу виконується лише одна макрозадача, зате мікрозадачі вичерпуються всі поспіль, доки черга не спорожніє. Тому пріоритет мікрозадач вищий. ```javascript setTimeout(() => console.log('macro'), 0); // Task Queue Promise.resolve().then(() => console.log('micro')); // Microtask Queue // micro, потім macro ``` **Ключове:** цикл такий: стек, усі мікрозадачі, одна макрозадача, і знову спочатку.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення**Мікрозадачі (microtasks) і макрозадачі (macrotasks) це різні черги задач, які обробляються в різний час усередині Event Loop.** Макрозадачі це «великі» події: таймери, мережеві запити, події DOM. Мікрозадачі це «миттєві» задачі, які виконуються одразу після поточного коду, але до наступної макрозадачі. ## Теорія ### TL;DR - Це дві окремі черги: `Task Queue` для макрозадач і `Microtask Queue` для мікрозадач. - Макрозадачі приходять від зовнішніх API браузера (Web API), мікрозадачі це вбудований механізм рушія JS. - За один оберт Event Loop виконується рівно одна макрозадача. - Мікрозадачі виконуються всі поспіль, доки їхня черга не спорожніє. - Пріоритет мікрозадач вищий: `Promise.then` завжди випереджає `setTimeout(..., 0)`. - Цикл виглядає так: порожній стек, усі мікрозадачі, наступна макрозадача, повтор. ### Швидкий приклад ```javascript console.log('1'); setTimeout(() => console.log('2'), 0); Promise.resolve().then(() => console.log('3')); console.log('4'); ``` Порядок виводу: ```text 1 4 3 2 ``` ### Порівняльна таблиця | Критерій | **Макрозадачі (Task Queue)** | **Мікрозадачі (Microtask Queue)** | | --- | --- | --- | | **Коли виконуються** | Після очищення стека і всіх мікрозадач | Одразу після поточного коду, перед макрозадачею | | **Черга** | `Task Queue` | `Microtask Queue` | | **Приклади** | `setTimeout`, `setInterval`, `setImmediate`, обробники подій, `XHR` | `Promise.then`, `Promise.catch`, `queueMicrotask`, `MutationObserver` | | **Пріоритет** | нижчий | вищий | | **Скільки виконується за раз** | Одна за ітерацію Event Loop | Усі мікрозадачі поспіль, доки черга не порожня | | **Джерело** | Зовнішні API браузера (Web API) | Вбудовані мікрозадачі рушія JS | | **Типова мета** | Відкладене виконання, асинхронні події | Реакція на завершення промисів, невеликі ланцюжки дій | ### Розбір прикладу 1. `1` і `4` виконуються синхронно, у стеку викликів. 2. `Promise.then(...)` потрапляє у **чергу мікрозадач**. 3. `setTimeout(...)` потрапляє у **чергу макрозадач**. 4. Після очищення стека виконуються **всі мікрозадачі**, що друкує `3`. 5. Потім виконується **перша макрозадача**, що друкує `2`. Зверніть увагу: порядок рядків у коді тут не має значення. Навіть якщо оголосити `setTimeout` першим, промис усе одно спрацює раніше, бо його колбек стоїть в іншій, пріоритетнішій черзі. ### Важлива деталь: що робить Event Loop після кожної макрозадачі Після кожної **макрозадачі** Event Loop: 1. виконує **всі мікрозадачі**, доки їхня черга не спорожніє, 2. потім бере **наступну макрозадачу**, 3. і повторює цикл. Саме тому мікрозадачі, додані всередині мікрозадачі, теж виконаються в цьому ж оберті, а не в наступному. ### Візуально ```text +-----------------------------------------------------+ | Виклики функцій (Call Stack) | |-----------------------------------------------------| | Мікрозадачі (Microtask Queue) | <- одразу після стека |-----------------------------------------------------| | Макрозадачі (Task Queue) | <- після мікрозадач +-----------------------------------------------------+ ``` ### Коротко про терміни | Що | Коли | Приклад | | --- | --- | --- | | **Мікрозадача** | Після поточного коду, до макрозадач | `Promise.then`, `queueMicrotask` | | **Макрозадача** | Після всіх мікрозадач | `setTimeout`, `setInterval`, події DOM | | **Event Loop** | Стежить за порядком: порожній стек, мікрозадачі, макрозадача, повтор | ціле керування циклом | ### Типові помилки - **Вважати, що черговість визначається порядком рядків у коді.** Її визначає черга, у яку потрапив колбек. - **Думати, що `setTimeout(..., 0)` це «виконати негайно».** Це найраніша можлива макрозадача, тобто після всіх мікрозадач. - **Плутати сам `fetch` із його `then`.** Мережева відповідь приходить через Web API, а ось колбек `then` це вже мікрозадача. - **Нескінченно породжувати мікрозадачі.** Черга ніколи не спорожніє, і макрозадачі разом з рендерингом не отримають керування. - **Розраховувати на однаковий порядок у браузері і в Node.js.** Набір джерел макрозадач відрізняється, наприклад `setImmediate` є лише в Node.js.Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.