同步触发所有事件处理程序是什么意思?

What does it mean that all event handlers are fired synchronously?

我对某些术语感到困惑。我试图找出 Node.js 的事件系统实际上是如何工作的,并且在很多地方我读到事件处理程序是完全同步的。

对我来说这似乎很奇怪,因为使用事件驱动方法的优点之一是主线程不会被事件阻塞。所以我试着想出我自己的例子,似乎发生的事情是我真正期望的:

const fs = require('fs')
const util = require('util')
const readFile = util.promisify(fs.readFile)

const events = require('events')
const emitter = new events.EventEmitter()

emitter.on('fire', () => {
  readFile('bigFile.txt')
    .then(() => console.log('Done reading bigFile.txt'))
    .catch(error => console.log(error))
  console.log('Sync thing in handler')
})

emitter.on('fire', () => {
  console.log('Second handler')
})

console.log('First outside')
emitter.emit('fire')
console.log('Last outside')

注意 bigFile.txt 实际上是一个很大的文本文件,在我的机器上处理它需要几百毫秒。

这里我先同步退出'First outside'。然后我引发启动事件处理过程的事件。事件处理程序确实似乎是异步的,因为即使我们先注销同步'Sync thing in handler'文本,我们开始使用后台线程池来return返回稍后读取文件的结果。在 运行 第一个处理程序之后,第二个处理程序运行打印出它的消息,最后我们打印出最后一个同步消息,'Last outside'。

所以我开始尝试证明一些人所说的,即事件处理程序本质上是同步的,然后我发现它们是异步的。我最好的猜测是,要么有人说事件系统是同步的,要么是我有一些概念上的误解。请帮助我理解这个问题!

EventEmitter class 与 emit 函数同步:事件处理程序从 [=12] 中同步调用=] 调用,正如您在 fire 事件中演示的那样,您自己解雇了。

一般来说,来自操作系统的事件(文件和网络操作、计时器等)通过节点的事件循环是异步的触发。你不是自己解雇他们,一些本地人 API 确实解雇了他们。当您收听这些事件时,您可以确定 .

The event handler does seem to be asynchronous, because even though we first log out the synchronous 'Sync thing in handler' text, we start using the thread pool in the background to return back with the result of reading the file later

是的,您正在调用异步函数 readFile(稍后会通知您),但这不会使您的事件侦听器函数或 .emit('fire') 调用异步。即使是启动后台进程的“异步函数”也会立即(同步)return 一些东西——通常什么都没有(undefined)或一个承诺。