Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to properly remove event listeners in node js eventemitter

I have a set up with a GET and a POST route, the idea being that POSTing to the route triggers an event, and the GET route is a server-sent eventstream which fires each time the POSTed event is triggered... however, i think i've done something wrong as event listeners seem to get added routinely despite only having one event stream subscriber... what am i doing wrong?

var events = require('events'), EventEmitter = events.EventEmitter, rr = new EventEmitter();  app.post('/api/:boardname/remoterefresh', function(req, res){     var boardname = req.param('boardname'),     data = new Date().getTime();     rr.emit("refresh-"+boardname, data)     res.json({data: data}) });  app.get('/api/:boardname/remoterefresh', function(req, res){     var boardname = req.param('boardname')      rr.on("refresh-"+boardname, function(data){         setTimeout(function(){             res.write('data: '+data+'\n\n');         }, 1000)     });      req.socket.setTimeout(Infinity);      res.writeHead(200, {         'Content-Type': 'text/event-stream',         'Cache-Control': 'no-cache',         'Connection': 'keep-alive'     });      res.write('\n');      req.on('close', function(){         console.log('closed')         rr.removeListener("refresh-"+boardname, function(){             //         })     })  }) 
like image 859
coffeedoughnuts Avatar asked May 27 '14 15:05

coffeedoughnuts


People also ask

How do I remove an event listener?

The removeEventListener() is an inbuilt function in JavaScript which removes an event handler from an element for a attached event. for example, if a button is disabled after one click you can use removeEventListener() to remove a click event listener.

Should you always remove event listeners?

TLDR; Always remove event listeners when you don't plan on using them any longer.

Do event listeners get removed?

According to the jquery Documentation when using remove() method over an element, all event listeners are removed from memory. This affects the element it selft and all child nodes. If you want to keep the event listners in memory you should use . detach() instead.

What happens if you don't remove event listeners?

The main reason you should remove event listeners before destroying the component which added them is because once your component is gone, the function that should be executed when the event happens is gone as well (in most cases) so, if the element you bound the listener to outlasts the component, when the event ...


2 Answers

You should name the function you attach as event handler. Then on removing it, you just pass the function by name:

app.get('/api/:boardname/remoterefresh', function(req, res){     var boardname = req.param('boardname')     function refreshHandler(data){         setTimeout(function(){             res.write('data: '+data+'\n\n');         }, 1000)     }     rr.on("refresh-"+boardname, refreshHandler);      req.socket.setTimeout(Infinity);      res.writeHead(200, {         'Content-Type': 'text/event-stream',         'Cache-Control': 'no-cache',         'Connection': 'keep-alive'     });      res.write('\n');      req.on('close', function(){         console.log('closed')         rr.removeListener("refresh-"+boardname, refreshHandler);     }); }); 

Basically removeListener will look up the given function by reference, if it found that function it will remove it from the event hander.

like image 91
Farid Nouri Neshat Avatar answered Oct 08 '22 05:10

Farid Nouri Neshat


To avoid referencing the anonymous listener callback function, you can dangerously wipe registered listeners with the emitter.removeAllListeners method:

rr.removeAllListeners("refresh-"+boardname) 

Be aware that this approach can easily result in unintended side-effects (deregistering listeners registered elsewhere in the codebase), and should be reserved for "wipe the slate clean" use cases (eg: Testing)

like image 40
goodhyun Avatar answered Oct 08 '22 05:10

goodhyun