简体   繁体   中英

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

I am confused about some terms. I am trying to find out how the event system of Node.js actually works, and in a lot of places I read that the event handlers are totally synchronous.

For me that seemed really strange, because one of the advantages of using an event-driven approach would be that the main thread would not be blocked by events. So I tried to come up with my own example, and it seems like that what did happen was what I actually expected:

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')

Note that bigFile.txt is an actually large text file, processing it takes a few hundred milliseconds on my machine.

Here I first log out 'First outside' synchronously. Then I raise the event which starts the event handling process. 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. After running the first handler, the second handler runs printing out its message, and finally we print out the last sync message, 'Last outside'.

So I started with trying to prove what some people say, which is that event handlers are by nature synchronous, and then I found them to be asynchronous. My best guess is that either people saying that the event system is synchronous mean something else, or that I have some conceptual misunderstanding. Please help me understand this issue!

The EventEmitter class is synchronous in regard to the emit function: event handlers are called synchronously from within the .emit() call, as you've demonstrated with the fire event you fired yourself.

In general, events that come from the operating system (file and network operations, timers etc) through node's event loop are fired asynchronously. You're not firing them yourself, some native API does fire them. When you listen to these events, you can be sure that they will occur not before the next tick .

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

Yes, you are calling the asynchronous function readFile (that will notify you later), but that doesn't make your event listener function or the .emit('fire') call asynchronous. Even "asynchronous functions" that start a background process will immediately (synchronously) return something - often nothing ( undefined ) or a promise.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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