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

Are there significant differences between the Chrome browser event loop versus the node event loop?

本文关键字:事件 循环 存在 之间 浏览器 节点 Chrome 是否      更新时间:2023-09-26

Philip Roberts在这里出色地解释了浏览器事件循环,在调用堆栈、事件循环、任务队列以及类似webapi的"外部"线程之间提供了清晰的解释。我的问题是,对Node事件循环中的等效组件进行并行处理,它们的调用是否基本相同。也就是说,当我使用Node的文件和web I/o库进行调用时,这些事情是否发生在回调在任务队列中排队的堆栈之外?

当我使用Node的文件和web I/o库进行调用时,这些都是在回调在任务队列中排队的堆栈之外发生的事情?

是的,绝对;它们是异步的,就像Ajax和setTimeout是异步的一样。它们在调用堆栈之外执行一些操作,完成该操作后,将事件添加到队列中,由事件循环处理。

Node的API提供了一种异步no-op setImmediate。对于该函数,我上面提到的"一些操作"是"什么都不做",之后一个项目会立即添加到事件队列的末尾。

有一个更强大的process.nextTick,它将一个事件添加到事件队列的前面,有效地插队并使所有其他排队的事件等待。如果递归调用,这可能会导致其他事件的延迟延长(直到到达maxTickDepth)。

两者截然不同。浏览器的事件循环不依赖于I/O操作。但是Node js事件循环依赖于I/O操作。这里Nodejs事件循环的主要目标是分离主进程,并尝试异步执行I/O操作和其他定时器API的操作。

另一个区别是我们在浏览器中没有函数setImmediate()。setTimeout()和setImmediate()的区别在于,在setTimeout)中,回调函数将在给定的最小阈值(以毫秒为单位)之后执行。但是在setImmediate()中,一旦完成任何I/O操作,如果在setImediate()内给定了特定的代码,它将首先执行。

因为通常

setTimeout(() => {
    //some process
}, 0);

setImmediate(() => {
    //some process
});

是相同的,我们无法预测哪个将首先执行。但是在nodejs事件循环机制下的nodejs透视图中,如果两者都存在于任何I/O操作的回调下,则setImmediate()将首先执行。所以,

let fs = require('fs');
fs.readFile('/file/path', () => {
   setTimeout(() => {
      console.log('1');
   }, 0);
   setImmediate(() => {
      console.log('2');
   });
});

上述代码的输出为

2
1

这是Erin Zimmer在JS会议上的另一个视频链接。她谈到了使用不同任务(如微任务和宏任务)以及其他环境(如NodeJS、浏览器和Web工作者)实现事件循环。

首先观看OP提到的Philip Roberts的视频,然后观看此视频。