Understand Events with Node.JS
A quick story on how Events really work with NodeJs.
The facts
We, on the team, realized that we did not read the documentation of Node Events that says that listeners of events are called synchronously :
The EventEmitter calls all listeners synchronously in the order in which they were registered. This is important to ensure the proper sequencing of events and to avoid race conditions or logic errors
This means that the following code will log “4” :
We (I) thought that the listener will be executed after the code, by adding the execution to the event loop, such as setImmediate :
We realized our mistake because we were doing something like, emitting an Event at the end of a SQL transaction :
So it means that if one of the listeners of either USER_CREATED or COMPANY_CREATED events throws an exception the transaction will be rolled back.
We (I) expected to fire the event and to forget it … but we (I) should not !.
I have to say (as a co-worker said) that it is very counterintuitive
How to solve this “counterintuitive” behavior
setImmediate
One solution can be to encapsulate all listeners in a setImmediate function, as it is shown in the Node.Js Documentation, so from our first example :
The use of Emittery
Emittery is a package that “solve” the behavior (remember this is not a bug …).
That’s quite good, and I have to say that it could be the solution we would try if we did not decide to migrate our event to messages using RabbitMQ, but this will be the next story.
Conclusion
First of all, you should read the F*** Manual before using a component or a library.
Use Emittery to be able to emit and listen to events as (I) expected.
Then come read the next story on how we migrate all events to RabbitMQ
Thank you for reading !
(Note this article was originally posted on my blog https://www.mimiz.fr/nodejs-events-are-counterintuitive.html)