Search code examples
javascriptnode.jseventsevent-loop

Which event loop phase event emitter callbacks are executed?


I have started learning node event loop, based on my understanding, other than setInterval, setImmediate, setTimeout callbacks, all will execute in poll phase, but when check with event emitter callbacks, its executes on every phase, lets say the below code

const EventEmitter = require('events');
const fs = require('fs');

const eventEmitter = new EventEmitter();
eventEmitter.on('emit', (eventName) => {
  console.log('<----- an event occurred! --->', eventName);
});

setTimeout(() => {
  setTimeout(() => {
    console.log(' setTimeout 0');
    eventEmitter.emit('emit', 'emit inside setTimeout 0');
  }, 0);

  setTimeout(() => {
    console.log(' setTimeout 5');
    eventEmitter.emit('emit', 'setInterval inside setTimeout 5');
  }, 5);

  process.nextTick(() => {
    console.log('process.nextTick');
    eventEmitter.emit('emit', 'emit inside process.nextTick');
  });

  Promise.resolve().then(() => {
    console.log('Promise.resolve()');
    eventEmitter.emit('emit', 'emit inside Promise.resolve()');
  });

  setImmediate(() => {
    console.log('setImmediate');
    eventEmitter.emit('emit', 'emit inside setImmediate 1');
  });

  fs.readFile(__filename, () => {
    console.log('fs.readFile');
    eventEmitter.emit('emit', 'emit inside fs.readFile');
  });


console.log('sync');
}, 0)

If i print the output it looks like below

sync
process.nextTick
<----- an event occurred! ---> emit inside process.nextTick
Promise.resolve()
<----- an event occurred! ---> emit inside Promise.resolve()
setImmediate
<----- an event occurred! ---> emit inside setImmediate 1
setTimeout 0
<----- an event occurred! ---> emit inside setTimeout 0
setTimeout 5
<----- an event occurred! ---> setInterval inside setTimeout 5
fs.readFile
<----- an event occurred! ---> emit inside fs.readFile

How this event emitter callback is executed as soon as event is emitted on every phase?


Solution

  • From node's docs about EventEmitter#emit():

    Synchronously calls each of the listeners registered for the event named eventName, in the order they were registered, passing the supplied arguments to each.

    The callbacks are called synchronously, so they're fired from whatever the phase the event-loop was in at the time emit() is called. If you're curious about a particular built-in event, you'd have to in the source where that event in particular is fired.