Выбор ответа Senior Event loop обновлено

Как дать браузеру отрисовать прогресс

Вопрос

Нужно обработать 100 000 элементов кусками по 1000 и между кусками обновлять прогресс-бар на экране. Каким способом планировать следующий кусок?

Попробуйте сами

Выберите вариант, и откроется разбор.

Показать ответ и разбор

Коротко

Правильный ответ: setTimeout(nextChunk, 0) (или scheduler.yield()). Отрисовка возможна только между задачами. setTimeout ставит следующий кусок отдельной задачей, и между кусками браузер успевает обработать ввод и нарисовать прогресс.

Варианты ответа

  1. Promise.resolve().then(nextChunk) после каждого куска
  2. queueMicrotask(nextChunk) после каждого куска
  3. Вызывать nextChunk() в цикле, но внутри async-функции
  4. setTimeout(nextChunk, 0) (или scheduler.yield())правильный ответ

Разбор

Отрисовка возможна только между задачами. setTimeout ставит следующий кусок отдельной задачей, и между кусками браузер успевает обработать ввод и нарисовать прогресс. Промисы и queueMicrotask создают микрозадачи: вся очередь выполнится подряд, без единого кадра, как один длинный синхронный цикл. Async-функция без await, отдающего управление задаче, тоже выполнится целиком. scheduler.yield() в Chromium делает то же, что таймер, но продолжение получает приоритет.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.

Термины по теме