Chrome浏览器事件循环与节点事件循环之间是否存在显着差异?

时间:2014-09-09 17:49:20

标签: javascript node.js javascript-events

Philip Roberts在解释浏览器事件循环here方面做得非常出色,在调用堆栈,事件循环,任务队列之间提供了清晰的解释,然后在"外部"像webapis这样的线程。我的问题是这些与Node事件循环中的等效组件并行,并且它们被称为基本相同的东西。也就是说,当我使用Node的文件和Web i / o库进行调用时,这些是在堆栈外发生的事情,其回调在任务队列中排队?

3 个答案:

答案 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的视频,然后再观看此视频。