为什么在文件读回调之前调用setImmediate?

时间:2017-02-15 09:12:07

标签: node.js callback 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 回调是在任何I / O操作之后的事件循环结束时运行的。但在我的情况下,在文件读取操作返回之前调用setImmediate回调。请解释为什么会发生这种情况或者setImmediate回调执行背后的逻辑是什么。

3 个答案:

答案 0 :(得分:1)

当程序开始执行时,

  1. setImmediate将进入事件循环。
  2. 接下来,fs.readFile也进入事件循环。
  3. 当程序完成执行时,它进入事件循环。它检查I / O回调挂起的内容。

    1. 现在,fs.readFile出现了。但它需要一个文件来阅读。因此它在操作系统内核中保留了一个fd(文件描述符)并说“当文件准备好读取时让我知道”。 [只是为了你的理解,它并没有真正说明这一行]并且甚至没有等待1纳秒。
    2. 现在下一个setImmediate将开始执行。
    3. 在事件循环中将文件打开到fd后,操作系统将返回fs.readFilefs.readFile现在将完成。
    4. 因此,setImmediate首先完成fs.readFile

答案 1 :(得分:0)

为什么你会期望fs.readFile()以不到一个滴答结束?特别是对于fs.readFile(),会发生多个操作:打开文件,读取一个或多个块以及关闭文件。这些操作需要相当长的时间(相对而言),并且在调用fs.readFile()回调之前可以轻松地执行多个事件循环。

答案 2 :(得分:0)

调用

setImmediate()函数以停止执行当前正在执行的函数并调用另一个函数来停止饥饿。它主要在I / O操作中调用,以阻止此函数占用cpu时间(在NodeJs异步调用时实现,因为它是单线程的)。 因此,它有助于无延迟地执行回调函数。

每当调用setImmediate()时,它都会返回事件循环(也称为uv_loop),以便执行等待执行的其他排队函数。

您也可以浏览此链接:setImmediate function

在您的代码中,

  

第1步,您正在调用正在运行的someAsyncOperation ()   同步,只需打印并在循环中等待100毫秒。

     

第2步,timeoutScheduled分配Date.now()

     

第3步,同样,someAsyncOperation ()被调用,它再次做同样的事情   事情(类似于第1步)

     

步骤4,它有一个I / O操作,即fs.readFile,在遇到这行代码后,它转到setImmediate()函数,   现在delay = Date.now() - timeoutScheduled(延迟将保留一个值   超过100因为显而易见的原因,因为它等待100毫秒   someAsyncOperation ()

     

setImmediate()之后,它返回到回调函数,而不是其他函数   fd已准备好立即执行。回调函数现在打印出来   适当的delay

     

,程序结束。