You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: 2-ui/99-ui-misc/03-event-loop/article.md
+16-16Lines changed: 16 additions & 16 deletions
Original file line number
Diff line number
Diff line change
@@ -1,13 +1,13 @@
1
1
2
-
# Цикл подій: мікрозавдання та макрозавдання
2
+
# Цикл подій (event loop): мікрозавдання (microtasks) та макрозавдання (macrotasks)
3
3
4
-
Потік виконання JavaScript в браузері, так само як і в Node.js, базується на *циклі подій*.
4
+
Потік виконання JavaScript в браузері, так само як і в Node.js, базується на *циклі подій (event loop)*.
5
5
6
6
Розуміння принципу роботи циклу подій важливе для оптимізації, та іноді для правильної архітектури.
7
7
8
8
В цьому розділі ми спочатку розглянемо теоретичну базу, а потім практичне застосування цих знань.
9
9
10
-
## Цикл подій
10
+
## Цикл подій (event loop)
11
11
12
12
Концепція *циклу подій* дуже проста. Існує нескінченний цикл, в якому рушій JavaScript очікує завдання, виконує їх, а потім переходить в режим очікування нових завдань.
13
13
@@ -17,7 +17,7 @@
17
17
- виконати їх, починаючи з найстарішого.
18
18
2. Очікувати поки завдання не з’явиться, потім перейти до пункту 1.
19
19
20
-
Це формалізація того, що ми бачимо, гортаючи веб-сторінку. Рушій JavaScript більшість часу не робить нічого, він працює лише коли спрацьовує скрипт, обробник подій чи подія.
20
+
Це формалізація того, що ми бачимо, гортаючи вебсторінку. Рушій JavaScript більшість часу не робить нічого, він працює лише коли спрацьовує скрипт, обробник подій чи подія.
21
21
22
22
Приклади завдань:
23
23
@@ -36,7 +36,7 @@
36
36
37
37
Наприклад, поки рушій виконує `script`, користувач може порухати мишкою, що спричинить появу події `mousemove`, та може вийти час, запрограмований в `setTimeout` і так далі. Ці завдання сформують чергу, як показано на схемі вище.
38
38
39
-
Задачі з черги виконуються за правилом "перший прийшов – перший пішов". Коли рушій браузера закінчить виконання `script`, він обробить подію `mousemove`, потім виконає обробник `setTimeout`, і так далі.
39
+
Задачі з черги виконуються за правилом "перший прийшов – перший пішов". Коли рушій браузера закінчить виконання `script`, він обробить подію `mousemove`, потім виконає обробник `setTimeout` тощо.
40
40
41
41
Доволі просто наразі, чи не так?
42
42
@@ -58,7 +58,7 @@
58
58
59
59
Щоб продемонструвати такий підхід, замість підсвічування для спрощення візьмемо функцію, яка рахує від `1` до `1000000000`.
60
60
61
-
Якщо ви запустите код нижче, рушій "зависне" на деякий час. Для серверного JS це буде явно видно, а якщо ви запускаєте це в браузері, то спробуйте понатискати інші кнопки на сторінці -- ви побачите, що жодна з подій не спрацює поки рахунок не завершиться.
61
+
Якщо ви запустите код нижче, рушій "зависне" на деякий час. Для серверного JS це буде явно видно, а якщо ви запускаєте це в браузері, то спробуйте понатискати інші кнопки на сторінці -- ви побачите, що жодна з подій не спрацює поки цей код не завершиться.
62
62
63
63
```js run
64
64
let i =0;
@@ -152,9 +152,9 @@ count();
152
152
153
153
Чому?
154
154
155
-
Все просто: як ви знаєте, в браузера є мінімальна затримка в 4мс при багатьох вкладених викликах `setTimeout`. Навіть якщо ми встановимо `0`, насправді це буде `4ms` (або трохи більше). Тож чим раніше ми заплануємо виклик - тим швидше виконається код.
155
+
Все просто: як ви знаєте, в браузера є мінімальна затримка в 4мс при багатьох вкладених викликах `setTimeout`. Навіть якщо ми встановимо `0`, насправді це буде `4ms` (або трохи більше). Тож чим раніше ми заплануємо виклик -- тим швидше виконається код.
156
156
157
-
Отож, ми розбили ресурсозатратне завдання на частини - тепер воно не буде блокувати користувацький інтерфейс. І загальний час виконання практично не збільшиться.
157
+
Отож, ми розбили ресурсозатратне завдання на частини -- тепер воно не буде блокувати користувацький інтерфейс. І загальний час виконання практично не збільшиться.
158
158
159
159
## Приклад 2: індикація прогресу
160
160
@@ -236,9 +236,9 @@ menu.onclick = function() {
236
236
};
237
237
```
238
238
239
-
## Макрозавдання та Мікрозавдання
239
+
## Макрозавдання (Macrotasks) та Мікрозавдання (Microtasks)
240
240
241
-
Разом з *макрозавданнями*, описаними в цьому розділі, існують *мікрозавдання*, описані в розділі <info:microtask-queue>.
241
+
Разом з *макрозавданнями (macrotasks)*, описаними в цьому розділі, існують *мікрозавдання (microtasks)*, описані в розділі <info:microtask-queue>.
242
242
243
243
Мікрозавдання приходять лише з нашого коду. Їх зазвичай створюють проміси: виконання обробника `.then/catch/finally` стає мікрозавданням. Мікрозавдання також використовуються "під капотом" `await`, так як це форма обробки проміса.
244
244
@@ -259,9 +259,9 @@ alert("code");
259
259
260
260
Який тут буде порядок виконання?
261
261
262
-
1.`code`покажеться першим, тому що це звичайний синхронний виклик.
263
-
2.`promise`покажеться другим, тому що `.then` проходить через чергу мікрозадач, і виконується після поточного синхронного коду.
264
-
3.`timeout`покажеться останнім, тому що це макрозавдання.
262
+
1.`code`буде показано першим, тому що це звичайний синхронний виклик.
263
+
2.`promise`буде показано другим, тому що `.then` проходить через чергу мікрозадач, і виконується після поточного синхронного коду.
264
+
3.`timeout`буде показано останнім, тому що це макрозавдання.
265
265
266
266
Більш детальна ілюстрація циклу подій виглядає так (порядок з верху до низу: спочатку script, потім мікрозавдання, рендеринг і так далі):
267
267
@@ -301,7 +301,7 @@ alert("code");
301
301
</script>
302
302
```
303
303
304
-
## Підсумок
304
+
## Підсумки
305
305
306
306
Більш детальний алгоритм циклу подій (хоч і спрощений порівняно зі [специфікацією](https://html.spec.whatwg.org/multipage/webappapis.html#event-loop-processing-model)):
307
307
@@ -316,15 +316,15 @@ alert("code");
316
316
Щоб додати в чергу нове *макрозавдання*:
317
317
- Використайте `setTimeout(f)` з нульовою затримкою.
318
318
319
-
Цей спосіб можна використати для розбиття великого важкообчислюваного завдання на частини, щоб браузер мав змогу реагувати на користувацькі події і показувати індикатор прогресу між ними.
319
+
Цей спосіб можна використати для розбиття великого ресурсозатратного завдання на частини, щоб браузер мав змогу реагувати на користувацькі події і показувати індикатор прогресу між ними.
320
320
321
321
Також це використовується в обробниках подій, щоб відкласти дію до моменту повної обробки події (вспливання завершене).
322
322
323
323
Щоб запланувати нове *мікрозавдання*
324
324
- Використайте `queueMicrotask(f)`.
325
325
- Також обробники промісів виконуються в черзі мікрозавдань.
326
326
327
-
Жодні UI або мережеві події не обробляються між мікрозавданнями: мікрозавдання виконуються негайно один за одним.
327
+
Жодні UI або мережеві події не обробляються між мікрозавданнями: мікрозавдання виконуються негайно одне за одним.
328
328
329
329
Тому `queueMicrotask` можна використати для асинхронного виконання фунції, але в одному й тому ж стані середовища.
0 commit comments