Most JavaScript event emitters (including Node's) are actually synchronous. This is extremely confusing if you happen to be coming from the browser, where events tend to be asynchronous. It's also confusing if you're used to promises, which guarantee that they will happen asynchronously. So, how can this trip us up?
Well, if we emit an event the handlers get called right then. And if one of them throws an error, it will blow out our current stack, not some amorphous future stack we don't care about.
var EE = require('events').EventEmitter var ee = new EE() ee.on('yolo', function (a) { // WARNING: If 'a' doesn't exit, this will throw. console.log(a.b) }) ee.emit('yolo') // Oh no... console.log('Is it safe?') // We don't get here.
We can also miss events if we aren't careful to listen for them before anyone else could emit them.
var EE = require('events').EventEmitter var ee = new EE() enterLottery(ee) ee.on('winner', function (amount) { // Could have had all this. while (amount--) { console.log('Omg omg omg we win!') } // But we weren't listening in tme. // We never knew we won. }) function enterLottery (emitter) { ee.emit('winner', 1000000000) }
There isn't one size fits all solution to these problems. Know that they exist, and be careful about them. There are very good performance and simplicity reasons for eventEmitters to not always be asynchronous by default. However consider emitting events in nextTick, to get them to happen as soon as possible, but asynchronously.
But for the love of god, make sure you don't release Zalgo .