Почему этот 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 ответа

Когда программа начинает выполнение,

  1. setImmediate войдет в цикл событий.
  2. Следующий, fs.readFile также входит в цикл обработки событий.

Когда программа завершает выполнение, она переходит в цикл обработки событий. Он проверяет ожидающие ответные вызовы ввода / вывода.

  1. Сейчас, fs.readFile входит в картину. Но ему нужен файл для чтения. Так что держит fd(дескриптор файла) в ядре ОС и говорит: "Дайте мне знать, когда файл будет готов к чтению" [просто для вашего понимания, в действительности это не говорит об этой строке] и возвращается, даже не ожидая 1 нано секунды.
  2. Теперь следующий setImmediate начнется выполнение.
  3. ОС вернется с 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() обратный вызов называется.

Другие вопросы по тегам