如何使setTimout函数以相同的速度运行

How can I make my setTimout functions run at the same speed?

本文关键字:速度 运行 何使 setTimout 函数      更新时间:2023-09-26

前言:我在我的个人网站上有一个关于这个问题的演示(我希望这没问题。如果没有问题,我可以尝试在jsfiddle上设置它)。我想让这个问题变得有趣一点,同时也试着理解javascript中函数所花费的时间。

我在超时时递增进度条的值。理想情况下(如果函数即时运行),它们应该以相同的速度填充,但在现实世界中,它们并没有。代码是这样的:

function setProgress(bar, myPer) {
bar.progressbar({ value: myPer })
    .children('.ui-progressbar-value')
        .html(myPer.toPrecision(3) + '%')
            .attr('align', 'center');
    myPer++;
    if(myPer == 100) { myPer = 0; }
 }
 function moveProgress(bar, myPer, inc, delay){
    setProgress(bar, myPer);
    if(myPer >= 100) { myPer = 0; }
    setTimeout(function() { moveProgress(bar, myPer+inc, inc, delay); }, delay);
 }
 $(function() { 
   moveProgress($(".progressBar#bar1"), 0, 1, 500);
   moveProgress($(".progressBar#bar2"), 0, 1, 500);
   moveProgress($(".progressBar#bar3"), 0, .1, 50);
   moveProgress($(".progressBar#bar4"), 0, .01, 5);             
 });

天真地,人们会认为应该以相同的速度运行(填满进度条)。

然而,在前两个栏中,(如果我们称"设置进度条"为单个操作)我每500毫秒执行一次操作,总共500次操作来填充栏;第三,我每50ms做一次手术,总共做了5000次手术来填满酒吧;在第四个步骤中,我每5毫秒进行一次操作,总共进行了50000次操作来填满酒吧。

我的代码的哪一部分耗时最长,导致了这些速度差异,并且可以进行更改,以使它们看起来像它们那样工作(第四条的增量较小),但也以相同的速度运行?

使用setTimeout进行此类操作的最大问题是,代码执行发生在超时之间,并且在发送给setTimeout的值中没有考虑。如果你的延迟是5毫秒,而你的代码需要5毫秒才能执行,那么你的时间实际上是加倍的。

另一个因素是,一旦触发超时,如果另一段代码已经在执行,它将不得不等待完成,从而延迟执行。

这与人们在尝试使用setTimeout作为时钟或秒表时遇到的问题非常相似。解决方案是将当前时间与程序启动的时间进行比较,并以此为基础计算时间。你也可以做类似的事情。检查您启动后的时间,并在此基础上设置%。

导致速度差异的原因有两件事:第一是您执行了更多的代码来填充底部栏(正如您在倒数第二段中提到的)。此外,每次设置超时时,浏览器都会将其排队。。。实际延迟可能比您指定的要长,这取决于队列中有多少(请参阅window.setTimeout上的MDN)。

喜欢这个问题,我没有一个非常精确的答案,但这是我的2美分:

Javascript是一种非常快速的语言,它能很好地处理它的事件循环,因此早餐吃setTimeouts和setIntervals
但也有限制,它们取决于大量因素,如浏览器和计算机速度、事件循环中的函数数量、执行代码的复杂性和超时值。。。

在这种情况下,我认为很明显,如果你尝试每500ms执行一个函数,它的表现会比每50ms执行一次好得多,因此比每5ms执行一次好得多。如果你考虑到你是在一个接一个地运行它们,你可以预测性能不会是最佳的。

您可以尝试以下练习:
拿500毫秒的那个,单独跑。记下填满条形图所需的总时间(就在这里,你会看到它将比预测的时间长一点)
试着同时执行两个500毫秒的超时,看看总时间变长了一点
如果你加上50毫秒,然后加上5毫秒,你会发现你每次都会失去表现。。。