与浏览器Javascript的事件侦听器相比,node.js中的事件包是如何工作的

与浏览器Javascript的事件侦听器相比,node.js中的事件包是如何工作的,javascript,node.js,events,event-handling,dom-events,Javascript,Node.js,Events,Event Handling,Dom Events,我对浏览器和node.js中的事件和事件处理程序的工作方式感到非常困惑 例如,在浏览器中,当我们有这样一个脚本时: 常数btnEl=。。。 addEventListener(“单击”,()=>console.log(“处理程序回调”); 对于(让索引=0;索引{ log(`startedfrom${start}到${end}`); }); 对于(让索引=0;索引

我对浏览器和node.js中的事件和事件处理程序的工作方式感到非常困惑

例如,在浏览器中,当我们有这样一个脚本时:


常数btnEl=。。。
addEventListener(“单击”,()=>console.log(“处理程序回调”);
对于(让索引=0;索引<100000;索引++){
console.log(索引)
}
我们都知道,在for循环期间,直到当前操作(当前匿名函数)结束,每个click事件都不会工作,因为调用堆栈不是空的,并且事件循环会将click消息排队,以便稍后调用

但在node.js中,我看到了不同的行为,如以下代码:


const EventEmitter=require(“事件”);
const eventEmitter=新的eventEmitter();
eventEmitter.on(“开始”,“开始,结束)=>{
log(`startedfrom${start}到${end}`);
});
对于(让索引=0;索引<20;索引++){
如果(索引==10){
eventEmitter.emit(“开始”,1100);
}否则{
控制台日志(索引);
}
}
在这段代码中,当我发出事件时,它会中断for循环中的当前循环,然后执行回调,这与Javascript引擎的单线程原则背道而驰

有人能给我解释一下为什么它是这样工作的吗

下面是第二个代码的输出:

0
1.
2.
3.
4.
5.
6.
7.
8.
9
从1开始到100
11
12
13
14
15
16
17
18
19

你的两个例子完全不同

eventEmitter.emit(“开始”,1100)是一段同步代码。它根本不经过事件循环。它只是一个函数调用,在
start
消息的任何侦听器中循环并调用这些侦听器。它只是简单的同步Javascript。他们称事物为“事件”这一事实可能会混淆事物,因为它们与事件循环无关

另一方面,浏览器中的用户单击会通过事件循环,需要Javascript解释器可用,这样它就可以抓取下一个等待的事件,然后调用单击处理程序

在nodejs中,传入事件(如传入网络连接或文件读取操作的完成)更类似于浏览器用户单击事件,因为它们通过事件循环,并且必须等待当前Javascript完成执行,因此可以从事件队列中提取下一个事件

仅供参考,如果您想在NodeJ中获得更具可比性的功能,请查看以下内容:

for (let index = 0; index < 20; index++) {
  if (index === 10) {
    setImmediate(() => eventEmitter.emit("start", 1, 100));
  } else {
    console.log(index);
  }
}
for(让索引=0;索引<20;索引++){
如果(索引==10){
setImmediate(()=>eventEmitter.emit(“start”,1100));
}否则{
控制台日志(索引);
}
}

然后,你强制
.emit()
通过事件循环,它将被延迟,直到
for
循环完成。

@charlietfl谢谢,我现在就知道了。谢谢你的帮助,伙计@MohammadMahdiMohajer-我在nodejs中添加了一个示例,使其通过事件循环。