Skip to content

Commit 757f084

Browse files
authored
Merge pull request #347 from xcurveballx/event-loop-minor
Event loop minor
2 parents 623e7ce + aa3f2b8 commit 757f084

1 file changed

Lines changed: 12 additions & 12 deletions

File tree

2-ui/99-ui-misc/03-event-loop/article.md

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
## Событийный цикл
1111

12-
Идея *событийного цикла* очень проста. Есть бесконечный цикл, в котором движок JavaScript ожидает задачи, исполняет их, и снова ожидает появления новых.
12+
Идея *событийного цикла* очень проста. Есть бесконечный цикл, в котором движок JavaScript ожидает задачи, исполняет их и снова ожидает появления новых.
1313

1414
Общий алгоритм движка:
1515

@@ -34,14 +34,14 @@
3434

3535
![](eventLoop.svg)
3636

37-
Например, когда движок занят выполнением скрипта, пользователь может передвинуть мышь, тем самым вызвав появление события `mousemove`, или может истечь таймер, установленный `setTimeout` и т.п. Эти задачи формируют очередь, как показано на иллюстрации выше.
37+
Например, когда движок занят выполнением скрипта, пользователь может передвинуть мышь, тем самым вызвав появление события `mousemove`, или может истечь таймер, установленный `setTimeout`, и т.п. Эти задачи формируют очередь, как показано на иллюстрации выше.
3838

39-
Задачи из очереди исполняются по правилу "первым пришел - первым ушёл". Когда браузер заканчивает выполнение скрипта, он обрабатывает событие `mousemove`, затем выполняет обработчик, заданный `setTimeout`, и так далее.
39+
Задачи из очереди исполняются по правилу "первым пришёл - первым ушёл". Когда браузер заканчивает выполнение скрипта, он обрабатывает событие `mousemove`, затем выполняет обработчик, заданный `setTimeout`, и так далее.
4040

4141
Пока что всё просто, не правда ли?
4242

4343
Отметим две детали:
44-
1. Рендеринг (отрисовка страницы) никогда не происходит во время выполнения задачи движком. Не имеет значение сколь долго выполняется задача. Изменения в DOM отрисовываются только после того, как задача выполнена.
44+
1. Рендеринг (отрисовка страницы) никогда не происходит во время выполнения задачи движком. Не имеет значения, сколь долго выполняется задача. Изменения в DOM отрисовываются только после того, как задача выполнена.
4545
2. Если задача выполняется очень долго, то браузер не может выполнять другие задачи, обрабатывать пользовательские события, поэтому спустя некоторое время браузер предлагает "убить" долго выполняющуюся задачу. Такое возможно, когда в скрипте много сложных вычислений или ошибка, ведущая к бесконечному циклу.
4646

4747
Это была теория. Теперь давайте взглянем, как можно применить эти знания.
@@ -54,7 +54,7 @@
5454

5555
Пока движок занят подсветкой синтаксиса, он не может делать ничего, связанного с DOM, не может обрабатывать пользовательские события и т.д. Возможно даже "подвисание" браузера, что совершенно неприемлемо.
5656

57-
Мы можем избежать этого, разбив задачу на части. Сделать подсветку для первых 100 строк, затем запланировать `setTimeout` (с нулевой задержкой) разметку следующих 100 строк, и т.д.
57+
Мы можем избежать этого, разбив задачу на части. Сделать подсветку для первых 100 строк, затем запланировать `setTimeout` (с нулевой задержкой) для разметки следующих 100 строк и т.д.
5858

5959
Чтобы продемонстрировать такой подход, давайте будем использовать для простоты функцию, которая считает от `1` до `1000000000`.
6060

@@ -160,11 +160,11 @@ count();
160160

161161
Ещё одно преимущество разделения на части крупной задачи в браузерных скриптах - это возможность показывать индикатор выполнения.
162162

163-
Обычно браузер отрисовывает содержимое страницы после того, как заканчивается выполнение текущего кода. Не имеет значения насколько долго выполняется задача. Изменения в DOM отображаются только после её завершения.
163+
Обычно браузер отрисовывает содержимое страницы после того, как заканчивается выполнение текущего кода. Не имеет значения, насколько долго выполняется задача. Изменения в DOM отображаются только после её завершения.
164164

165165
С одной стороны, это хорошо, потому что наша функция может создавать много элементов, добавлять их по одному в документ и изменять их стили -- пользователь не увидит "промежуточного", незаконченного состояния. Это важно, верно?
166166

167-
В примере ниже, изменения `i` не будут заметны, пока функция не завершится, поэтому мы увидим только последнее значение `i`:
167+
В примере ниже изменения `i` не будут заметны, пока функция не завершится, поэтому мы увидим только последнее значение `i`:
168168

169169

170170
```html run
@@ -220,7 +220,7 @@ count();
220220

221221
В обработчике события мы можем решить отложить некоторые действия, пока событие не "всплывёт" и не будет обработано на всех уровнях. Мы можем добиться этого, обернув код в `setTimeout` с нулевой задержкой.
222222

223-
В главе <info:dispatch-events> мы видели пример: наше событие `menu-open` генерируется через `setTimeout`, чтобы возникло после того, как полностью обработано событие "click".
223+
В главе <info:dispatch-events> мы видели пример: наше событие `menu-open` генерируется через `setTimeout`, чтобы оно возникло после того, как полностью обработано событие "click".
224224

225225
```js
226226
menu.onclick = function() {
@@ -244,7 +244,7 @@ menu.onclick = function() {
244244

245245
Также есть специальная функция `queueMicrotask(func)`, которая помещает `func` в очередь микрозадач.
246246

247-
**Сразу после каждой *макрозадачи* движок исполняет все задачи из очереди *микрозадач* перед тем, как выполнить следующую макрозадачу или отобразить изменения на странице или сделать что-то ещё.**
247+
**Сразу после каждой *макрозадачи* движок исполняет все задачи из очереди *микрозадач* перед тем, как выполнить следующую макрозадачу или отобразить изменения на странице, или сделать что-то ещё.**
248248

249249
Например:
250250

@@ -267,11 +267,11 @@ alert("code");
267267

268268
![](eventLoop-full.svg)
269269

270-
**Все микрозадачи завершаются до обработки каких-либо событий или рендеринга или перехода к другой макрозадаче.**
270+
**Все микрозадачи завершаются до обработки каких-либо событий или рендеринга, или перехода к другой макрозадаче.**
271271

272-
Это важно, так как гарантирует, что общее окружение остаётся одним и тем же между микрозадачами - не изменены координаты мыши, не получены новые данные по сети, и т.п.
272+
Это важно, так как гарантирует, что общее окружение остаётся одним и тем же между микрозадачами - не изменены координаты мыши, не получены новые данные по сети и т.п.
273273

274-
Если мы хотели бы запустить функцию асинхронно (после текущего кода), но до отображения изменений и до новых событий, мы можем запланировать это через `queueMicrotask`.
274+
Если бы мы хотели запустить функцию асинхронно (после текущего кода), но до отображения изменений и до новых событий, то мы могли бы запланировать это через `queueMicrotask`.
275275

276276
Вот пример с индикатором выполнения, похожий на предыдущий, но в этот раз использована функция `queueMicrotask` вместо `setTimeout`. Обратите внимание - отрисовка страницы происходит только в самом конце. Как и в случае обычного синхронного кода.
277277

0 commit comments

Comments
 (0)