使用NodeJS全局事件通过进程是一个好主意吗?

3

我需要使用setInterval每隔N秒向数据库进行查询,并将结果发送给所有的Socket.IO客户端,所以我会这样做:

let interval_id = null

io.on('connection', function(socket) {
    if (interval_id == null) {

        interval_id = setInterval(function() {
            db.table.items.getAll().then(function(items) {
                process.emit('items_found', items)
            }).catch(function(err) {
                log.error(err)
            })
        }, config.scan.interval)
    }

    process.on('alarms_found', function(alarms) {
        console.log(alarms.length)
    })
})

它运行得很好,但我是NodeJS的新手,不知道其他做法...一般来说,我明白使用全局范围不是最好的选择,但我不知道其他方法...


看起来你每次连接都要查询数据库。这可能不是个好主意。最好将新连接注册到某个地方,一次查询数据库,然后将结果发送到每个连接。 - Daniel Diekmeier
@DanielDiekmeier 连接没问题。这里有单例模式。同时,还有一个 if 语句来确保 setInterval 函数只运行一次。 - Kiril
1个回答

2
  • 如果您的真实代码与复杂度和量方面相同或相似,那么这种方法不会带来任何问题。Process对象是一个EventEmitter,在这里您有效地利用了它。
  • 如果不是这样,最好使用自己的eventemitter,而不是process对象。按设计,它代表运行节点过程的重要参数,如执行环境、节点模块和其他操作系统抽象。EventEmitter继承帮助它管理进程生命周期事件。
  • 将其混杂在自定义应用程序数据流中不会引起任何功能问题,但当应用程序增长时,维护和问题确定变得困难。例如,如果您也恰好在每个间隔存储“警报”(完全或部分),则存储对象将无限增长且永远不会被垃圾回收。ii)即使完成了与DB相关的活动,侦听器仍将保持活动状态,以及它占用的任何内存。在这种情况下,您实际上可以通过命名回调函数(比如foo),并在不需要时通过process.removeListener('alarms_found', foo)删除回调函数来解决该问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接