准确的javascript睡眠功能

Posted

技术标签:

【中文标题】准确的javascript睡眠功能【英文标题】:Accurate javascript sleep function 【发布时间】:2019-10-21 16:40:30 【问题描述】:

我正在使用 javascript 定期发送一组请求(每个 5 ms)。

我尝试使用setTimeoutsleep function,但它们都没有准确的时间。

他们确保时间间隔为>= 5ms 而不是== 5ms。 有什么想法吗?

看来这在javascript中很难实现甚至是不可能的!!

这是我正在使用的代码:

function sleep(ms) 
    return new Promise(resolve => setTimeout(resolve, ms));




async function sendRequest() 
    var i;
    for (i=1; i<= numberOfRequests; i++)
        // send my i^th request here
        await sleep(5);
    

【问题讨论】:

看看await sleep(5); 我认为你不能保证 == 5ms 部分。您可以保留时间戳,当 setTimeout 回调运行时,检查最后一个时间戳并确定它所花费的确切时间。不确定这是否有帮助,但这是我所看到的 - 如果需要任何计算,那么可以通过实际时间与预期时间的增量来调整它们。 @axelaxel 如果你的意思是this,那么它仍在使用setTimeout,所以它不能保证延迟 How to create an accurate timer in javascript?的可能重复 【参考方案1】:

没有任何方法可以在任何编程语言中提供准确的超时,因为它们存在于通用多道程序操作系统中。发生这种情况是因为操作系统将其时间片分配给特定进程的确切时间是不可预测的。

此外,JavaScript 是单线程的,它与event loop system 一起工作,异步任务(如 setTimehout、xhr 回调、点击侦听器等)只有在当前所有代码完成后才会执行。例如,如果您有:

setTimeout(() => console.log('hello world'), 500);
for (let i = 0; i<1E100; i++) 
  console.log(Math.sqrt(i));

Hello world 只有在所有计算完成后才会打印出来。

【讨论】:

但是不准确太重要了,有时一秒钟有时更多…… 那么你应该把你的同步代码拆分成几个异步任务。这清楚地表明你有太多同步代码 "JavaScript 是单线程的" 但它不是。 很多时候,你写的代码会在单线程中运行,但是 JS 本身并不是单线程的。您可以让Workers 进入多线程编程,浏览器也可以在单独的线程中运行每个选项卡。 嗯,NodeJS 也可以使用多个线程,这取决于环境上下文。但我们常说它是单线程的,因为如果您使用更多线程,那么您就知道自己在做什么 顺便说一句,关于如何中断同步任务以允许执行异步函数的问题,但我再也找不到了。如果有人记得它,你能把它链接到 OP 吗?【参考方案2】:

由于 javascript 使用单线程事件循环,因此无法获得这种准确性。事件循环中的事件在引擎完成前一个任务时执行。如果您将任务设置为在 20 毫秒后执行(setTimeout、setInterval 或任何其他自定义任务),引擎会将该任务添加到事件循环中,然后它将尝试从循环中运行任何其他任务(假设一个函数需要25 毫秒运行)。由于 javascript 是单线程的,因此您可以从循环中启动任何其他元素,直到 25 毫秒的任务完成。在这种情况下,您的超时将在 25 毫秒后开始,即使您将其设置为 20。这就是 javascript 架构的工作原理。

即使您实现了多线程(工作者、线程等),事件循环仍将存在于每个线程中(每个线程都有自己的循环)

【讨论】:

以上是关于准确的javascript睡眠功能的主要内容,如果未能解决你的问题,请参考以下文章

javascript 简单的JavaScript睡眠功能

javascript / node.js中的睡眠功能[重复]

JavaScript 中是不是有睡眠/暂停/等待功能? [复制]

如何在Javascript中制作精确的睡眠功能,可能使用承诺?

是否有等效的 Javascript 或 Jquery 睡眠功能?

循环中 Promise 的 javascript 睡眠功能