繁体   English   中英

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

[英]How does events package work in node.js in contrast of event listeners of browser Javascript

我真的很困惑事件和事件处理程序是如何在浏览器和 node.js 中工作的。

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


const btnEl = ...

btnEl.addEventListener("click" ,() => console.log("handler callback"));

for (let index = 0; index < 100000; index++) {
  console.log(index)
}

我们都知道,在 for 循环期间,直到当前操作结束,即当前匿名 function,每个点击事件都不会起作用,因为调用堆栈不为空,事件循环会将点击消息排队等待稍后调用.

但是在 node.js 我看到了不同的行为,比如这段代码:


const EventEmitter = require("events");

const eventEmitter = new EventEmitter();

eventEmitter.on("start", (start, end) => {
  console.log(`started from ${start} to ${end}`);
});

for (let index = 0; index < 20; index++) {
  if (index === 10) {
    eventEmitter.emit("start", 1, 100);
  } else {
    console.log(index);
  }
}

在这段代码中,当我发出事件时,它在for循环中打破当前循环,然后执行回调,这违背了Javascript引擎的单线程原则。

有人可以向我解释为什么它会这样工作吗?

这是第二个代码的output:

0
1
2
3
4
5
6
7
8
9
started from 1 to 100
11
12
13
14
15
16
17
18
19

你的两个例子完全不同。

eventEmitter.emit("start", 1, 100); 在 nodejs 中是一段同步的代码。 它根本不会通过事件循环 go 。 这只是一个 function 调用,循环遍历所有侦听器以获取start消息并调用这些侦听器。 这只是普通的同步 Javascript。 他们称事物为“事件”这一事实可能会使事情变得混乱,因为它们与事件循环无关。

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

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

仅供参考,如果您想要在 nodejs 中更具可比性,请查看以下内容:

for (let index = 0; index < 20; index++) {
  if (index === 10) {
    setImmediate(() => eventEmitter.emit("start", 1, 100));
  } else {
    console.log(index);
  }
}

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM