edit full article archive to publication standard
Build and deploy / deploy (push) Successful in 18s
Build and deploy / deploy (push) Successful in 18s
This commit is contained in:
@@ -119,7 +119,7 @@ const practiceArticle = createRevision(
|
||||
readingMinutes: 11,
|
||||
},
|
||||
[
|
||||
paragraph('Симптом обычно формулируют неточно: «асинхронность поменяла порядок» или «таймер не сработал вовремя». На странице это выглядит конкретнее: обработчик <code>Promise.then</code> пишет в лог раньше <code>setTimeout</code>, а после импорта данных кнопка несколько мгновений не отвечает. Если начать менять задержки на глаз, можно скрыть один запуск и оставить ту же блокировку на другом устройстве.'),
|
||||
paragraph('Симптом обычно формулируют неточно: «асинхронность поменяла порядок» или «таймер не сработал вовремя». На странице это выглядит конкретнее: обработчик <code>Promise.then</code> пишет в лог раньше <code>setTimeout</code>, а после импорта данных кнопка несколько мгновений не отвечает. Если начать менять задержки на глаз, можно скрыть один запуск и оставить ту же блокировку на другом устройстве. Цена ошибки — потерянное действие пользователя и повторная отправка данных.'),
|
||||
paragraph('Ниже не «объяснение магии Promise», а маленький воспроизводимый маршрут. Мы сначала записываем порядок синхронных строк, Promise-реакции и timer callback. Потом отдельно создаём длинную синхронную работу и измеряем её границы через <code>performance.now()</code>. Так одна проблема распадается на две: неожиданная очередность и занятый главный поток.'),
|
||||
heading('Что именно наблюдаем'),
|
||||
paragraph('В браузерном коде есть как минимум текущий вызов JavaScript, задачи, которые выбирает event loop, и microtask checkpoint. Promise-реакция не прерывает уже исполняющуюся функцию. Она попадает в работу после того, как текущий стек освободится. Callback таймера тоже не появляется в середине этой функции: истекшая задержка делает его кандидатом на будущую задачу. Отсюда первое правило: «через ноль миллисекунд» означает не «немедленно».'),
|
||||
@@ -218,7 +218,7 @@ const mechanismArticle = createRevision(
|
||||
readingMinutes: 12,
|
||||
},
|
||||
[
|
||||
paragraph('Сбой начинается с простой фразы в ревью: «поставим <code>await</code>, тогда браузер успеет отрисовать кнопку». Иногда кнопка действительно меняется на конкретной машине, но причина не доказана. Promise-реакция не может вклиниться в середину уже идущей JavaScript-функции. Если перед <code>await</code> был тяжёлый parse или цикл, интерфейс уже ждал; если после <code>await</code> снова идёт тяжёлая работа, он будет ждать следующую границу.'),
|
||||
paragraph('Сбой начинается с простой фразы в ревью: «поставим <code>await</code>, тогда браузер успеет отрисовать кнопку». Иногда кнопка действительно меняется на конкретной машине, но причина не доказана. Promise-реакция не может вклиниться в середину уже идущей JavaScript-функции. Если перед <code>await</code> был тяжёлый parse или цикл, интерфейс уже ждал; если после <code>await</code> снова идёт тяжёлая работа, он будет ждать следующую границу. Цена ошибки — увеличить число ожиданий, не освободив главный поток.'),
|
||||
paragraph('Разберём механизм без слишком широкой метафоры «у JavaScript одна очередь». В языке есть Jobs и host hooks, а в браузере — event loop, задачи, microtask checkpoint и шаги рендеринга. Для прикладного кода достаточно держать три вопроса: какая работа сейчас на стеке, что поставлено как microtask и какой callback ждёт будущую задачу. Эта тройка объясняет неожиданный порядок Promise и timer без выдуманной точности таймера.'),
|
||||
heading('Три слоя, которые не стоит смешивать'),
|
||||
paragraph('Стек исполнения — это то, что выполняется прямо сейчас. Пока синхронная функция не вернулась, браузер не переключит JavaScript на другой callback того же event loop. ECMAScript описывает Jobs как абстрактные единицы работы и определяет host hook для постановки Promise Job. Браузер связывает эту языковую часть с microtask queue: когда он дошёл до checkpoint, накопленные microtasks выполняются до перехода к обычной следующей задаче.'),
|
||||
|
||||
Reference in New Issue
Block a user