Можно ли выполнять более приоритетные промисы кроме setTimeout и что это дает пользователю
Что проверяют
Понимаете ли вы устройство event loop целиком: задачи, микрозадачи, отрисовку. И главное, различаете ли «выполнится раньше» и «интерфейс станет отзывчивее», потому что это разные вещи. Следом спрашивают, как разбить долгую операцию, чтобы не страдал INP.
Как отвечать
Сам промис не «выполняется» с приоритетом: executor в new Promise() отрабатывает синхронно, а приоритет есть у колбэков. Порядок выглядит так:
- микрозадачи:
.thenи.catch, продолжение послеawait,queueMicrotask(),MutationObserver. Очередь опустошается целиком сразу после текущей задачи, до отрисовки и до следующегоsetTimeout; requestAnimationFrame: срабатывает перед ближайшей отрисовкой кадра, место для изменений DOM и анимаций;- макрозадачи:
setTimeout,MessageChannel, события. УsetTimeoutс вложенностью глубже пяти уровней браузер поднимает задержку минимум до 4 мс, уMessageChannelтакого ограничения нет, поэтому планировщик React использует именно его; scheduler.postTask(): явные приоритетыuser-blocking,user-visible,background, плюсscheduler.yield(), чтобы уступить поток и продолжить без потери очереди. Поддержка есть не во всех браузерах, нужна проверка'scheduler' in window;requestIdleCallback: фоновая работа, когда браузер простаивает.
Что это даёт пользователю. Микрозадачи позволяют довести состояние до конца до отрисовки, без промежуточных кадров и мигания. Отзывчивость же даёт обратное: длинную задачу дробят и уступают поток браузеру через макрозадачи или scheduler.yield(), чтобы между кусками он успел обработать ввод и нарисовать кадр.
Где спотыкаются
Считают, что Promise.resolve().then(...) разгружает поток. Цепочка микрозадач блокирует отрисовку так же, как синхронный цикл, а бесконечная просто вешает вкладку.
Путают порядок и думают, что setTimeout(fn, 0) сработает раньше колбэка уже выполненного промиса.
Дробят долгую работу через await на готовых промисах и ждут улучшения INP. Все продолжения остаются микрозадачами одной задачи, и браузер так и не получает шанса отрисовать кадр.