如何正确删除节点 js eventemitter 中的事件侦听器
Posted
技术标签:
【中文标题】如何正确删除节点 js eventemitter 中的事件侦听器【英文标题】:How to properly remove event listeners in node js eventemitter 【发布时间】:2014-07-16 15:05:55 【问题描述】:我设置了一个 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()
//
)
)
)
【问题讨论】:
Unbinding events in Node.js 的可能重复项 这会导致竞争条件和跨请求泄漏数据吗? 【参考方案1】:为避免引用匿名侦听器回调函数,您可以使用emitter.removeAllListeners 方法危险地擦除已注册的侦听器:
rr.removeAllListeners("refresh-"+boardname)
请注意,这种方法很容易导致意外的副作用(取消注册在代码库中其他地方注册的侦听器),并且应该保留用于“彻底清除”用例(例如:测试)
【讨论】:
请注意,rr.removeAllListeners
(复数形式)是正确的名称
我还发现我需要使用 removeAllListeners,当 removeListener 似乎无法识别也与 function.bind(this) 绑定的类中的方法名称时,也许这不起作用.【参考方案2】:
您应该将附加的函数命名为事件处理程序。然后在删除它时,您只需按名称传递函数:
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
将通过引用查找给定函数,如果找到该函数,它将从事件处理程序中删除它。
【讨论】:
以上是关于如何正确删除节点 js eventemitter 中的事件侦听器的主要内容,如果未能解决你的问题,请参考以下文章
eventemitter.emit 方法不会在节点 js 中返回
反应式编程 - Node.js 中的 RxJS 与 EventEmitter
实战Node.js原理对于阻塞和EventEmitter及其继承的运用心得
(节点:6261)MaxListenersExceededWarning:检测到可能的 EventEmitter 内存泄漏