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 承诺睡眠时间太长的主要内容,如果未能解决你的问题,请参考以下文章

为啥 nodejs 中的睡眠不能按预期工作

javascript Nodejs简单的睡眠

睡到特定时间/日期

c# 里的Thread.sleep()最长睡眠时间

HP笔记本怎么调睡眠状态

智能睡眠评估系统(包含:睡眠数据特征工程睡眠评分睡眠聚类睡眠可视化分析睡眠结论存储)