Read this SO question first: Removing event listener which was added with bind
Now that we’re on the same page. I’m going to make this short’n’sweet by providing a premise and letting the code do the talking: The example provided in the SO post was all fine and dandy, but was for the case of single-use. I needed a way to clean up event listeners on a Node.js net.Server and associated socket connections.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
/* * First, the setup: * 1. bring in deps * 2. create an object that will be an emitter * 3. inherit the core events emitter functionality * 4. register a method that will eventually emit an event * 5. staticDefinition is just some plain-old function we might use * 6. instantiate our custom event emitter class * The actual "ah-ha!" is after the setup. */ var events = require('events'); var util = require('util'); var EventClass = function() {}; util.inherits(EventClass,events.EventEmitter); EventClass.prototype.emitSomething = function(name) { var t = process.hrtime(); this.emit.apply(this,[name,t[0]*1e9+t[1],name].concat(Array.prototype.slice.call(arguments,1))); }; function staticDefinition() { console.log.apply(console,['staticDefinition'].concat(Array.prototype.slice.call(arguments,0))); } var inst = new EventClass(); /* eventsTable is used to keep track of bound events within a specific scope/ns * notice this is a kvp table, i.e. { 'eventName': function eventHandler(){} } * so multiple listeners on a single event won't work * but this shows how something like this be implemented */ var eventsTable = {}; // first, let's show the typical way of doing things inst.on('simple',staticDefinition); // register event listener inst.emitSomething('simple',1,2); // do something to trigger the underlying emitter console.log(inst.listeners('simple').length); // 1, we see that it has an emitter for our event inst.removeListener('simple',staticDefinition); // usual way of removing it console.log(inst.listeners('simple').length); // 0, works, the listener was removed // this will dynamically attach a bunch of events with diff parameters that have been manipulated with bind ['one','two','three'].forEach(function(eventName,key) { var specificDefinition = staticDefinition.bind(inst,'custom'+key); // each definition is unique eventsTable[eventName] = specificDefinition; // register the event in the table inst.on(eventName,specificDefinition); // bind it }); // try to remove the listener with the basic function definition inst.emitSomething('one',3,4); console.log(inst.listeners('one').length); // 1 inst.removeListener('one',staticDefinition); // doesn't work console.log(inst.listeners('one').length); // 1 // try to remove the listener with the exact bind spec (new function definition) inst.emitSomething('two',5,6); console.log(inst.listeners('two').length); // 1 inst.removeListener('two',staticDefinition.bind(inst,'two')); // doesn't work console.log(inst.listeners('two').length); // 1 inst.emitSomething('three',7,8); console.log(inst.listeners('three').length); // 1 inst.removeListener('three',eventsTable['three']); // works console.log(inst.listeners('three').length); // 0 |