如何在节点js eventemitter中正确删除事件侦听器

时间:2014-05-27 15:56:11

标签: javascript node.js express eventemitter event-stream

我有一个GET和POST路由的设置,想法是POST到路由触发一个事件,而GET路由是服务器发送的事件流,每次触发POSTed事件时触发...然而,我认为我做错了事情,因为事件听众似乎经常加入,尽管只有一个事件流订阅者......我做错了什么?

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(){
            //
        })
    })

})

2 个答案:

答案 0 :(得分:39)

您应该将附加的函数命名为事件处理程序。然后在删除它时,您只需按名称传递函数:

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);
    });
});

基本上removeListener将通过引用查找给定的函数,如果它找到该函数,它将从事件处理程序中删除它。

答案 1 :(得分:0)

或者您也可以

rr.removeAllListener(["refresh-"+boardname])

不引用匿名侦听器回调函数。