Skip to content
Advertisement

NodeJS Nested Event listeners

I don’t get it, Why passed argument to the event emitter with nested event listeners streams all values? Is it because it has to pass through the upper level ‘join’ listener? Is variable information stored somewhere?

var events = require('events');
var net = require('net');
var channel = new events.EventEmitter();
var i  = 0; 
var subscriptions;

// IF we have two connections
channel.on('join', function(subs) { // Upper Listener

    console.log(subs); // -> output 0 when first client joined and 1 for second

    channel.on('broadcast', function(subs2) { // lower listener
        console.log(subs); // Stream of all connections: -> 0 and 1 ???
        console.log(subs2); // Outputs last connection -> 1
    });
});

var server = net.createServer(function(client) {

    subscriptions = i++;                  // variable to pass

    channel.emit('join', subscriptions); // pass the same variable

    client.on('data', function(data) {
        channel.emit('broadcast', subscriptions); // pass the same variable
    });
});
server.listen(7000);

This creates TCP server. Then you can join with tellnet localhost 7000,

Answer

Please replace channel.on(‘broadcast’,…) with channel.once(‘broadcast’,…). So use ‘once’ subscription which will remove the ‘broadcast’ listener once handled.

For each ‘join’ subscription we had a ‘broadcast’ subscription. Lets say after 3 joins there will be three subscription to ‘broadcast’ event. So when the emitter emits with ‘broadcast’ all three subscription is called. The value of sub is the previous value and only sub2 is updated.

The modified code will look like this. I kind of put some additional console logs for better understanding.

var events = require('events');
var net = require('net');
var channel = new events.EventEmitter();
var i  = 0;
var subscriptions;

// IF we have two connections
channel.on('join', function(subs) { // Upper Listener

    console.log("join:subs:"+subs); // -> output 0 when first client joined and 1 for second

    channel.once('broadcast', function(subs2) { // lower listener
        console.log('came to broadcast');
        console.log("broadcast:subs:" + subs); // Stream of all connections: -> 0 and 1 ???
        console.log("broadcast:subs2:"+subs2); // Outputs last connection -> 1
    });
});

var server = net.createServer(function(client) {

    subscriptions = i++;                  // variable to pass

    channel.emit('join', subscriptions); // pass the same variable

    client.on('data', function(data) {
        console.log('received data:'+data);
        channel.emit('broadcast', subscriptions); // pass the same variable
    });
});
server.listen(7000);
Advertisement