我正在 Node.js 中编写 WebSocket 客户端,我想对消息数据执行异步操作(即存储在数据库中),但同时也要确保按照收到消息的顺序一次一个地操作。
为了达到这个目的,我在onMessage处理程序中把消息推送到一个数组中,同时使用一个调用自己的函数把消息从数组中移出。就像这样。
const flushQueue = async () => {
const nextMessage = messageQueue.shift();
await doSomethingAsync(nextMessage); // i.e. store in db, etc.
flushQueue();
}
撇开我的系统是否能跟上的问题不谈,这个方法很好用, 除了脚本最终会用完堆内存。一个简单的测试表明,将一个元素从数组中移出,实际上 增加 而我的假设是,它减少了所使用的内存。
const a = [1,2,3,4,5,6];
a.shift();
a.shift();
console.log(process.memoryUsage());
为什么从数组中删除一个元素会增加进程使用的内存量?我如何以节省内存的方式无限期地存储我的一组排队的 WebSocket 消息?
我几乎可以肯定问题出在你的尾部调用上,而不是移动数组。Node和Javascript没有适当的尾部调用优化。一些 统计学 和 在TCO上任职.
长时间运行的循环如果没有尾部调用优化,最终会耗尽内存。
我会放弃这个自定义队列,直接写到数据库。
SQLite + 更好的-sqlite3 司机是一个好的开始。
// pseudo-code example (not tested)
ws.on('message', function incoming (data) {
const stmt = db.prepare('INSERT INTO list(message) VALUES(?)')
const result = stmt.run(data) // synchronous in-process write
// do something with result or something else
});