Alexander Mills Alexander Mills - 16 days ago 6
Node.js Question

Remove all event emitter listeners, except most recent

Looking to find a way to remove all listeners except for the most recently added listener.

So for process.stdin, we might do

process.stdin.on('readable',function a(){});
process.stdin.on('readable',function b(){});
process.stdin.on('readable',function c(){});


I want to remove callbacks a and b, but leave c.

However, in this case I don't have a reference to a or b, I want to do something like:

while(process.stdin.listenerCount('readable') > 1){
process.stdin.removeListener('readable');
}


but I think you need to pass a function in. Any way around this?

Answer

You can retrieve a copy of handlers for a particular event via eventEmitter.listeners(). However, you really should not rely on them being in a particular order.

Here is one such solution that currently works:

process.stdin.listeners('readable').forEach(function(fn) {
  if (process.stdin.listenerCount('readable') > 1)
    process.stdin.removeListener('readable', fn);
});

If you know the name of the one function you want to keep, then you can instead just branch on fn.name instead, like:

process.stdin.listeners('readable').forEach(function(fn) {
  if (fn.name !== 'c')
    process.stdin.removeListener('readable', fn);
});

One thing to also be aware of is that if you remove these listeners from a 'readable' event handler, then the other listeners will still be called for that particular event (but not future events). This is because the listeners for an event name are cloned before any of them are called during .emit().

Comments