setImmediate и setTimeout внутри I/O-колбэка
Вопрос
Код выполняется внутри колбэка fs.readFile. Что гарантированно выведется первым?
fs.readFile(__filename, () => {
setTimeout(() => console.log("timeout"), 0);
setImmediate(() => console.log("immediate"));
});
Попробуйте сами
Выберите вариант, и откроется разбор.
Показать ответ и разбор
Коротко
Варианты ответа
timeout: нулевой таймер всегда срабатывает раньше setImmediate- Порядок не определён, как и в главном модуле
immediate: после poll идёт check, таймеры на следующем кругеправильный ответimmediate, потому что setImmediate это микрозадача
Разбор
Колбэк readFile выполняется в фазе poll. Следующая фаза check, там выполняются колбэки setImmediate, и только потом цикл возвращается к фазе timers. Поэтому внутри I/O-колбэка immediate всегда первый.
Недетерминированность бывает в главном модуле: там порядок зависит от того, успела ли пройти 1 мс (минимальная задержка таймера) к моменту входа в цикл. Поэтому вариант «порядок не определён» верен только для главного модуля. setTimeout(fn, 0) не «всегда раньше», а setImmediate это макрозадача фазы check, не микрозадача.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.
Предыдущий вопрос
p99 вырос в 10 раз, CPU 40%: как ищешь причину
Следующий вопрос
Что на самом деле идёт в пул потоков libuv
Термины по теме
Ещё по теме «Event loop и libuv»
- Тяжёлый цикл без блокировки event loop
- Код-ревью: что блокирует event loop
- Что блокирует event loop
- Объясни event loop в Node.js
- setImmediate и setTimeout внутри I/O
- setTimeout(0) против setImmediate на верхнем уровне
- Что такое libuv
- Рекурсивный process.nextTick