Почему Node.js setImmediate выполняется после обратных вызовов ввода-вывода?
Как новый участник, я не могу комментировать темы, поэтому мне пришлось создать новую тему. Но таким образом я могу прояснить проблему, так что, надеюсь, вы, ребята, сможете мне помочь.
Я много читал о Node.js Event Loop. И я сформировал свое понимание этого на основе следующих материалов:
Цикл событий Node.js
Какого черта цикл событий в любом случае?
Почему setImmediate() выполняется перед fs.readFile() в работах Nodejs Event Loop?
(Пожалуйста, не стесняйтесь предлагать другие материалы, которые являются информативными и точными)
Особенно третья ссылка дала мне лучшее понимание. Но, помня об этом, я не могу понять поведение цикла событий для следующего кода:
var fs = require('fs');
var pos = 0;
fs.stat(__filename, function() {
console.log(++pos + " FIRST STAT");
});
fs.stat(__filename, function() {
console.log(++pos + " LAST STAT");
});
setImmediate(function() {
console.log(++pos + " IMMEDIATE")
})
console.log(++pos + "LOGGER");
Удивительно, но для меня вывод таков:
LOGGER
FIRST STAT
LAST STAT
IMMEDIATE
снимок экрана моего терминала, показывающий вывод, а также версию узла
скриншот вывода из онлайн-кода компилятора rextester.com
Учитывая диаграмму цикла событий, я предполагаю, что поток должен быть следующим:
- Интерпретатор сначала запускает две операции статистики.
- Очереди интерпретатора обратного вызова setImmedate (событие) в очереди setImmedate
- Стек вызовов записывает в журнал
- Все очереди событий до фазы опроса ввода / вывода пусты, поэтому цикл обработки событий (EL) продолжается
- На этапе опроса ввода / вывода EL собирает события и ставит в очередь оба обратных вызова fs.stat на этапе "Выполнить обработчики ввода / вывода"
- EL проверяет фазу проверки и запускает обратный вызов setImmediate
- Этот раунд EL заканчивается, и начинается второй раунд
- В "запустить завершенные обработчики ввода / вывода" EL запускает оба обратных вызова (их порядок может быть onn-определенным)
Вопрос 1: Какая часть моего анализа / прогноза неверна?
Вопрос 2: В какой момент Event Loop начинает работать? Это начинается с начала приложения (то есть стадии 1)? или он запускается после того, как интерпретатор читает весь код, все задачи синхронизации выполняются в стеке вызовов, а стеку вызовов требуется больше задач, то есть между этапами 3-4?
Заранее спасибо,
1 ответ
setImmediate = выполнить без ожидания ввода-вывода
В https://nodejs.org/docs/v8.9.3/api/timers.html говорится:
Планирует "немедленное" выполнение обратного вызова после обратных вызовов событий ввода / вывода. Возвращает Immediate для использования с clearImmed
шаги:
- обратный вызов для первой статистики в очереди ввода / вывода
- обратный вызов для последней статистики ставится в очередь в очереди ввода / вывода
- обратный вызов для немедленной очереди в очереди немедленных
- ЛЕСОЗАГОТОВИТЕЛИ
- Если операции ввода / вывода (в 1 и 2) завершены, обратные вызовы в 1 и / или 2 помечаются как готовые к выполнению
- Выполните готовые обратные вызовы один за другим (сначала тиммер, затем ввод-вывод, наконец, немедленный). В твоем случае:
- Первый стат
- Последняя статистика
- ЛЕСОЗАГОТОВИТЕЛИ
В случае, если I / O не заканчивается в 5.
тогда LOGGER выполнялся до FAT STAT и LAST STAT.
Смотрите также: https://jsblog.insiderattack.net/timers-immediates-and-process-nexttick-nodejs-event-loop-part-2-2c53fd511bb3