如何使setTimout函数以相同的速度运行
How can I make my setTimout functions run at the same speed?
前言:我在我的个人网站上有一个关于这个问题的演示(我希望这没问题。如果没有问题,我可以尝试在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毫秒,你会发现你每次都会失去表现。。。
- 画布动画似乎不会以60帧/秒的速度运行
- Jquery.hide()和.show()在firefox上运行速度较慢,但在chrome上运行良好
- 我的jQuery运行有点慢.我该如何加快速度
- setTimeout在运行过程中更改速度
- 设置为“run_at”document_start“的 Chrome 扩展程序运行速度太快
- 为什么 setInterval 以不同的速度运行
- 使用速度运行 Tinytest
- Angular ng repeat+filter在iphone4s上运行速度慢得离谱
- ThreeJS场景以60FPS的速度运行,但让我的粉丝们兴奋不已,最终崩溃了
- 为什么我的网站在从手机打开时速度很慢,但在从桌面打开时运行良好
- 如何使setTimout函数以相同的速度运行
- 循环中的异步函数运行速度太慢.我该如何提高表现
- Chrome v54中的Web worker在非活动选项卡中运行时速度慢两倍
- CSS3运行时的转换速度
- 动画运行速度较慢,并且在chrome中没有重新加载页面就不能重播
- 是否有一种方法可以强制非活动选项卡以正常速度运行JavaScript
- 以相同速度运行的Javascript游戏循环
- 我可以以60fps的速度运行angular's digest loop来显示快速计时器吗?
- 再次触发时,计时器会以两倍的速度运行
- 以4倍速度运行Javascript时钟