skip to Main Content

I just started exploring Node JS event-driven architecture and event loop, What I understand is that Event emitters enter into the Event Loop which should be asynchronous but when I execute below I see event emitters are logged first and then top-level code.

const EventEmitter = require("events");
const myEmitter = new EventEmitter();
myEmitter.on('newSale', () => { 
    console.log('New sale received');
})
myEmitter.on('newSale', (saleValue) => {
console.log('New sale received from John Doe', + saleValue);
})
myEmitter.emit('newSale', 29); 
console.log('Top level code');

My assumption and expectation is that, If event emitters enter into the event loop then top-level code should be executed and then event loop code (in our case event emitters) should be executed.

As per my expectation below should be the order of the logs.

  1. Top level code
  2. New sale received
  3. New sale received from John Doe 29

But below is the actual logs which are getting printed.

  1. New sale received
  2. New sale received from John Doe 29
  3. Top level code

Any help in understanding the above is appreciated.

2

Answers


  1. What I understand from few of the blogs is that Event emitters enters into the Event Loop …

    I am not sure whether you misunderstood or the blogs you referred to are misleading. But Event-Loop and EventEmitter are completely different things that cause a lot of misunderstandings because of the word Event...

    From the Node Documentation: https://nodejs.org/api/events.html

    The EventEmitter calls all listeners synchronously in the order in which they were registered

    When the EventEmitter object emits an event, all of the functions attached to that specific event are called synchronously. To make it Asynchronous you have to use setImmediate(), setTimeout() process.nextTick() approaches.

    More Info: https://nodejs.org/api/events.html#asynchronous-vs-synchronous

    const EventEmitter = require("events");
    
    const myEmitter = new EventEmitter();
    
    myEmitter.on('newSale', () => {
        console.log('New sale received');
    });
    
    myEmitter.on('newSale', (saleValue) => {
        console.log('New sale received from John Doe', + saleValue);
    });
    
    setImmediate(() => myEmitter.emit('newSale', 29));
    
    console.log('Top level code');
    
    

    The above script will print the output as you expected.

    Top level code
    New sale received
    New sale received from John Doe 29
    

    Here the EventEmitter does not automatically enter into the EventLoop. By invoking setImmediate() we tell the Node to execute it Asynchronously.

    Login or Signup to reply.
  2. The code that you have posted is synchronous in nature i.e. it will be executed in the same manner it is picked. EventEmitter in Node.js are synchronous which means they are executed into the execution context as soon as they get in.

    My assumption and expectation is that, If event emitters enters into
    the event loop then top level code should be executed and then event
    loop code (in our case event emitters) should be executed.

    No, this is not the case, they are executed synchronously in the same execution phase of the event loop in which they are triggered.

    Check how execution will take place:

    const EventEmitter = require("events");  // picked and executed
    
    const myEmitter = new EventEmitter(); // picked and executed
    
    myEmitter.on('newSale', () => { 
        console.log('New sale received');
    }) // picked and registered in the same eventloop phase
    
    myEmitter.on('newSale', (saleValue) => {
    console.log('New sale received from John Doe', + saleValue);
    
    }) // picked and registered in the same eventloop phase
    
    myEmitter.emit('newSale', 29); // calling the registered events and producing o/p in the same sequence 'newSale' events are registered
    
    console.log('Top level code'); // Once all the events are executed, this will be picked.
    

    As per my expectation below should be the order of the logs.

    Top level code
    New sale received
    New sale received from John Doe 29

    This is only possible when you put the events in an asynchronous code as mentioned by BadPiggie. There are other ways to make it asynchronous.

    You can use process.nextTick, setTimeout, and setImmediate to make it asynchronous. You should read about how Node.js executes them in what event loop queues. There are a lot of blogs available to get to know about them.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search