NodeJS 承诺睡眠时间太长
Posted
技术标签:
【中文标题】NodeJS 承诺睡眠时间太长【英文标题】:NodeJS sleep with promise takes too long 【发布时间】:2021-09-05 17:00:54 【问题描述】:我正在尝试提高使用队列处理工作人员传入消息的性能。
但是,睡眠功能需要 16 到 30 毫秒才能完成,而不是 1 毫秒。有没有更好的方法来处理队列而不会有这么大的延迟,并且不会让我的应用保持 100% cpu?
我正在做这样的事情:
var actions = new Queue();
parentPort.on('message', (msg) => actions.enqueue(msg));
loopy();
async function loopy()
while (true)
if (actions.size() > 0)
let action = actions.dequeue();
//do work
continue;
await sleep(1);
function sleep(ms)
return new Promise(resolve => setTimeout(resolve, ms));
任何帮助将不胜感激。谢谢!
【问题讨论】:
回到事件循环(这是setTimeout()
所做的)有与之相关的开销,因为事件循环除了下一个计时器之外还有其他事情要检查。因此,没有办法在 nodejs 中等待恰好 1ms。这里更相关的是为什么你要在一个while循环中等待1ms?你希望用它来完成什么?您可能应该扭转您的问题并描述您想要完成的工作,然后我们可以帮助您以其他/更好的方式来完成它,而不是您现在拥有的或尝试依赖不是为该工作设计的时间安排。
这能回答你的问题吗? What is the reason javascript setTimeout is so inaccurate?
@jfriend00 我会用其他语言来做这件事,但是那些是多线程的,它不能很好地翻译成 JS。我试图一步解决两个不同的问题(保持活力与过程动作)。我选择使用 Ricky Mo 的回答。 sleep 是为了避免使用 100% cpu 和无限循环。
【参考方案1】:
while(true)
(通常)不是一个好主意。
将消息排入队列后,您应该调用 dequeue 函数。出队函数应该在 1. 已经有出队函数在运行 2. 队列中没有更多消息时结束。
var isProcessing = false;
var actions = new Queue();
parentPort.on('message', (msg) =>
actions.enqueue(msg)
tryDequeue();
);
async function tryDequeue()
if(isProcessing || actions.size() == 0)
return;
isProcessing = true;
let action = actions.dequeue();
//do work
isProcessing = false;
tryDequeue();
【讨论】:
我明天试试这个并报告。我使用循环来避免阻塞消息处理程序,但我看到你的没有睡眠也有同样的效果。我想我还需要让工人活着,所以我使用了循环。while (true)
如果在循环中有 await
是完全可以的。就这样一次就好了。我认为更大的问题是他们为什么要睡 1 毫秒。那是为了什么?不多。
我接受这个答案,因为它通过完全避免睡眠来解决我遇到的问题。然后,为了让工作人员保持活力,我可以使用 set Interval
并延迟很长时间。以上是关于NodeJS 承诺睡眠时间太长的主要内容,如果未能解决你的问题,请参考以下文章