这是一个例子:
const http = require('http');
let startTime = Date.now();
http.createServer((req,res)=>{
console.log('hello');
res.end('nice');
}).listen(8888,()=>{
console.log('server listened at port 8888');
});
setTimeout(function() {
console.log('hei,I am 5000 timeout function' + `time past ${Date.now()-startTime}`);
}, 5000);
setImmediate(()=>{
console.log('hei,I am immediate function' + `time past ${Date.now()-startTime}`);
})
结果:
server listened at port 8888
hei,I am immediate functiontime past 14
hei,I am 5000 timeout functiontime past 5016
但是在我看来,setImmediate
回调应该在5000ms之后运行,因为http异步网络I / O应该阻止事件循环5000ms,因为超时是由setTimeout
设置的。但结果显示I/O pool
阶段的事件循环立即返回。为什么?事件循环中的代码:
timeout = 0;
if ((mode == UV_RUN_ONCE && !ran_pending) || mode == UV_RUN_DEFAULT)
timeout = uv_backend_timeout(loop);
uv__io_poll(loop, timeout);
uv__run_check(loop);
uv_backend_timeout()
中的:
diff = handle->timeout - loop->time;
if (diff > INT_MAX)
diff = INT_MAX;
return diff;
因此I/O pool
中的超时应为5000毫秒,然后uv_epoll_wait()
应阻止事件循环5000毫秒,然后转到check
阶段。所以我很困惑为什么setImmediate
回调如此早地运行。
答案 0 :(得分:0)
setTimeout函数是nodejs中的非阻塞函数。它不会阻止主事件循环。如果你真的想阻止事件循环,那么使用wait函数。