Philip Roberts在解释浏览器事件循环here方面做得非常出色,在调用堆栈,事件循环,任务队列之间提供了清晰的解释,然后在"外部"像webapis这样的线程。我的问题是这些与Node事件循环中的等效组件并行,并且它们被称为基本相同的东西。也就是说,当我使用Node的文件和Web i / o库进行调用时,这些是在堆栈外发生的事情,其回调在任务队列中排队?
答案 0 :(得分:11)
...当我使用Node的文件和Web i / o库进行调用时,这些是在堆栈外发生的事情,其回调在任务队列中排队吗?
是的,绝对的;他们像Ajax一样异步,setTimeout
是异步的。它们在调用堆栈之外执行一些操作,当它们完成该操作时,它们将事件添加到队列以由事件循环处理。
Node的API提供了一种异步无操作setImmediate
。对于该功能,"某些操作"我上面提到的是"什么都不做"之后,一个项目立即被添加到事件队列的末尾。
有一个功能更强大的process.nextTick
,可以向事件队列的前端添加一个事件,有效地切入行并使所有其他排队事件等待。如果以递归方式调用,这可能会导致其他事件延迟(直到达到maxTickDepth
)。
答案 1 :(得分:0)
两者都有很大的不同。浏览器的事件循环不取决于 I / O操作。但是Node js事件循环取决于 I / O操作。这里,Node js事件循环的主要目标是分离主要进程,并尝试异步执行I / O操作和其他计时器API。
另外一个区别是,浏览器中没有功能 setImmediate()。 setTimeout()和setImmediate()之间的差异为:在setTimeout()中,回调函数将在给定的最小阈值(以毫秒为单位)之后执行。但是在setImmediate()中,一旦完成任何I / O操作,如果在setImmediate()中提供了特定的代码,它将首先执行。
因为通常是
setTimeout(() => {
//some process
}, 0);
和
setImmediate(() => {
//some process
});
相同,我们无法预测哪个将首先执行。但是在Nodejs事件循环机制下的Node js透视图中,如果两者都存在于任何I / O操作的回调中,则将首先执行 setImmediate()。所以,
let fs = require('fs');
fs.readFile('/file/path', () => {
setTimeout(() => {
console.log('1');
}, 0);
setImmediate(() => {
console.log('2');
});
});
以上代码的输出将为
2
1
答案 2 :(得分:0)
这是Erin Zimmer的另一个视频link,他在JS大会上发表了影片。她谈到了事件循环的实现,其中包括微任务和宏任务以及其他环境(如Node JS,浏览器和Web worker)中的不同任务。
首先观看OP提到的Philip Roberts的视频,然后再观看此视频。