Nodejs Событие L oop - взаимодействие с кодом верхнего уровня - PullRequest
1 голос
/ 13 февраля 2020

в надежде получить небольшое подтверждение понимания модели исполнения node.js. Я понимаю, что когда начинается процесс node.js, это последовательность выполнений: enter image description here (из курса Удеми node.js Йонаса Шмедтмана)

При этом главный вынос Код уровня всегда выполняется первым до любых обратных вызовов.

Затем, в событии -l oop, это последовательность 'фаз': enter image description here

После некоторого копания я также подтвердил, почему setTimeout и setImmediate, вызываемые в основном модуле, имеют «произвольный» порядок выполнения, но при вызове из фазы ввода / вывода setImmediate всегда будет выполняться первым, на основании этого поста: https://github.com/nodejs/help/issues/392#issuecomment -274032320 .

(Причина: при условии, что порог таймера уже пройден, так как мы в настоящее время находимся в фазе ввода-вывода, а следующей фазой после этого является фаза обработчиков проверок, где выполняются обратные вызовы setImmediate, немедленный всегда выполняется до того, как таймер.)

Теперь, когда таймер и немедленные обратные вызовы вызываются из фазы, такой, что следующей фазой является фаза должных таймеров (например, из основного модуля), если код верхнего уровня занял достаточно много времени, чтобы таймер истекает, обратный вызов таймера всегда будет выполняться первым, правильно? Я проверил это с помощью следующего кода, и, похоже, это правда (каждый раз, когда я его запускаю, таймер запускается первым, хотя с полной задержкой по сравнению с немедленным обратным вызовом)

setTimeout(() => {
  console.log('timer completed');
}, 1000);

setImmediate(() => {
  console.log('immediate completed');
});

for (let i = 0; i < 5000; i++) {
  console.log(`top-level code: ${i}`);
}

Итак, вот мой вопрос: не следует ли выполнять обратный вызов операции ввода-вывода перед обратным вызовом непосредственного из-за события -l oop, предполагая, что код верхнего уровня занимает достаточно много времени, чтобы операция ввода-вывода завершилась к тому времени, когда мы начнем событие-l oop?

Тем не менее, этот код ниже предлагает иное, так как порядок выполнения всегда: top-level-> timer-> немедленное-> io

Хотя на основе приведенной выше модели следует ожидать : верхние уровни-> таймер-> io-> немедленный (?)

setTimeout(() => {
  console.log('timer completed');
}, 1000);

fs.readFile('test-file.txt', 'utf-8', () => {
  console.log('io completed');
});

setImmediate(() => {
  console.log('immediate completed');
});

for (let i = 0; i < 5000; i++) {
  console.log(`top-level code: ${i}`);
}

Спасибо!

...