查看这些代码行
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回调执行背后的逻辑是什么。
答案 0 :(得分:1)
当程序开始执行时,
setImmediate
将进入事件循环。fs.readFile
也进入事件循环。 当程序完成执行时,它进入事件循环。它检查I / O回调挂起的内容。
fs.readFile
出现了。但它需要一个文件来阅读。因此它在操作系统内核中保留了一个fd
(文件描述符)并说“当文件准备好读取时让我知道”。 [只是为了你的理解,它并没有真正说明这一行]并且甚至没有等待1纳秒。 setImmediate
将开始执行。 fd
后,操作系统将返回fs.readFile
。fs.readFile
现在将完成。因此,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
值,程序结束。