Search code examples
javascriptnode.jseventsevent-handlingatomic

Reading and writing global variables in event handlers: when is concurrency an issue ?


I'm new to Node.JS and I started to read several topics about Node.js event handling and concurrency.

The bit of code following fires 1000 times an event, which is handled by incrementing a global variable. The first bit of code successfully counts to 1000, but the second bit doesn't even increment to 2. Is there any atomicity I don't get ?

I'm still wondering why the following code gives a coherent output (it counts successfully to 1000 without any concurrency:

// Import events module
var events = require('events');

// Event emitter
var eventEmitter = new events.EventEmitter();

var max = 1000;

var count = 0;

eventEmitter.on('event', () => {
    let time = Math.trunc(Math.random() * 1000) +1;
    setTimeout(() => {  
        var c = count;
        c++;
        count = c;
        console.log(c);  
    }, time);
});

// Fire
for (let i = 0; i < max; i++) {
    eventEmitter.emit('event');
}

console.log('Program Ended.');

Is there any atomicity I don't get ?

But when I move the var creation & assignation, the output is radically different (the final result is 1).

// Import events module
var events = require('events');

// Event emitter
var eventEmitter = new events.EventEmitter();

var max = 1000;

var count = 0;

eventEmitter.on('event', () => {
    let time = Math.trunc(Math.random() * 1000) +1;
    var c = count;
    setTimeout(() => {  

        c++;
        count = c;
        console.log(c);  
    }, time);
});

// Fire
for (let i = 0; i < max; i++) {
    eventEmitter.emit('event');
}

console.log('Program Ended.');

Any advice ? Any reading ?

Have a nice day !


Solution

  • From Bergi's provided external resources:

    All Javascript event handler scripts are handled from one master event queue. This means that event handlers run one at a time and one runs until completion before the next one that's ready to go starts running. As such, there are no race conditions in Javascript. Any individual thread of execution in javascript will run to completion before the next one starts.

    From this.

    And:

    One event will run to completion before the next event is triggered. So, if a second click occurs while the first is still processing, the second click will be queued and will not run until the code processing the first one is done.

    From that