Почему этот setImmediate вызывается перед обратным вызовом чтения файла?
Посмотрите на эти строки кода
function someAsyncOperation () {
console.log("inside someAsyncOperation");
var startCallback = Date.now();
// do something that will take 10ms...
while (Date.now() - startCallback <= 100) {
; // do nothing
}
}
someAsyncOperation();
var timeoutScheduled = Date.now();
setImmediate(function () {
var delay = Date.now() - timeoutScheduled;
console.log(delay + "ms have passed since I was scheduled");
});
someAsyncOperation();
fs.readFile("./noor.txt",function(err,data){
var delay = Date.now() - timeoutScheduled;
console.log(delay + "file read");
});
Как я узнал, обратный вызов setImmediate запускается в конце цикла событий после любой операции ввода-вывода. Но в моем случае обратный вызов setImmediate вызывается до завершения операции чтения файла. Пожалуйста, объясните, почему это происходит или какова логика выполнения обратного вызова setImmediate.
3 ответа
Когда программа начинает выполнение,
setImmediate
войдет в цикл событий.- Следующий,
fs.readFile
также входит в цикл обработки событий.
Когда программа завершает выполнение, она переходит в цикл обработки событий. Он проверяет ожидающие ответные вызовы ввода / вывода.
- Сейчас,
fs.readFile
входит в картину. Но ему нужен файл для чтения. Так что держитfd
(дескриптор файла) в ядре ОС и говорит: "Дайте мне знать, когда файл будет готов к чтению" [просто для вашего понимания, в действительности это не говорит об этой строке] и возвращается, даже не ожидая 1 нано секунды. - Теперь следующий
setImmediate
начнется выполнение. - ОС вернется с
fd
после открытия файла вfs.readFile
в цикле событий.fs.readFile
будет закончено сейчас.
Так, setImmediate
закончен первым, чем fs.readFile
,
setImmediate()
Функция вызывается для того, чтобы остановить выполнение текущей выполняемой функции и вызвать другую функцию, чтобы остановить голодание. Он в основном вызывается при операциях ввода-вывода, чтобы остановить эти функции, чтобы израсходовать время процессора (реализовано при асинхронных вызовах NodeJ, так как оно является однопоточным). Таким образом, это помогает выполнять функцию обратного вызова без каких-либо задержек.
Всякий раз, когда setImmediate()
вызывается, он возвращается обратно в цикл обработки событий (также известный как uv_loop) для выполнения других функций в очереди, ожидающих выполнения.
Вы также можете перейти по этой ссылке: функция setImmediate
В вашем коде
Шаг 1, вы звоните
someAsyncOperation ()
который работает синхронно, просто печатает и ждет 100 мс в цикле.Шаг 2, timeoutScheduled назначает
Date.now()
Шаг 3, снова
someAsyncOperation ()
призвал, который снова делает то же самое (похоже на шаг 1)Шаг 4, он получил одну операцию ввода-вывода, т.е.
fs.readFile
после встречи с этой строкой кодаsetImmediate()
функция, сейчасdelay = Date.now() - timeoutScheduled
(задержка будет содержать значение более 100 по очевидной причине, так как она ожидает 100 мс вsomeAsyncOperation ()
после
setImmediate()
, он возвращается к функции обратного вызова, как никакой другойfd
готов к исполнению сейчас. Функция обратного вызова теперь печатает соответствующийdelay
значениеи программа заканчивается.
Почему вы ожидаете fs.readFile()
закончить менее чем за галочку? Особенно для fs.readFile()
происходит несколько операций: открытие файла, чтение одного или нескольких фрагментов и закрытие файла. Эти операции занимают значительное количество времени (условно говоря) и могут легко занять более одного тика цикла событий до того, как fs.readFile()
обратный вызов называется.