setInterval上的时间似乎不准确

时间:2015-12-12 20:15:29

标签: javascript settimeout setinterval

我正在编写一些javascript来更改当前显示的图像的不透明度,使其看起来褪色,然后将图像更改为其他图像。我将图像更改设置为setInterval等待5000毫秒。淡入淡出的setInterval设置为从4000毫秒开始。 setTimeout被调用10次,所有等待100毫秒,弥补了淡出setInterval等待前的时间与ChangeImage setInverval等待前的时间之间的差异。

var num, lastNum = 0, count = 10, tcount = 0.0;
var file = "images/image-", ext = ".jpg", image, temp;
var f1 = "alpha(opacity=", f2 = ")";

window.onload = setTimeout(Initialize, 0);
window.onload = setInterval(ImageFader, 4000);
window.onload = setInterval(ChangeImage, 5000);

function Initialize()
{
    image = document.getElementById('title-image');
    image.src = "images/image-1.jpg";
}

function ChangeImage()
{
    image = document.getElementById('title-image');
    do
    {
        num = Math.floor((Math.random() * 10) + 1);
    } while (num == lastNum);
    lastNum = num;
    temp = file.concat(num.toString());
    image.src = temp.concat(ext);
}

function ImageFader()
{
    setTimeout(Fade, 100);
}

function Fade()
{
    tcount = count / 10;
    image.style.opacity = tcount;
    f1 = f1.concat((tcount * 100).toString());
    image.style.filter = f1.concat(f2);

    if (count > 1)
    {
        count--;
        setTimeout(Fade, 100);
    }
    else
    {
        count = 10;
        image.style.opacity = 1;
        image.style.filter = "alpha(opacity=100)";
    }
}

我真的很困惑为什么时间不匹配,因为他们应该。第一张图像的淡入效果很好。它消失的地方然后在正确的时间移动到下一个图像。但从那时起,时机变得不同步。褪色发生但图像在正确的时间没有变化。

3 个答案:

答案 0 :(得分:0)

Fade()方法的执行时间肯定会成为问题的一部分。

您所处的环境。 Real-time operating systems承诺在一定时间内执行任务,并且每次都按时执行。 (有一些例外。我正在简化。)

同样没有任何操作系统的嵌入式系统可以非常容易预测 - 因为代码行之间没有任何事情发生。如果您可以精确确定A点和B点之间出现的CPU周期数,则可以保证一切都按时发生。

您正在做的是尝试使用非实时操作系统在尽可能远离嵌入式系统的环境中实现如此精确的时序!

即使我们忽略了你的操作系统(托管浏览器)永远不能保证你想要它们会发生的事实(你在浏览器中无法用JS解决这个问题)你仍然遇到问题 - setTimeout(Fade, 100)行实际上给你更多100.5ms的延迟,因为所有这些代码必须首先执行:

tcount = count / 10;
image.style.opacity = tcount;
f1 = f1.concat((tcount * 100).toString());
image.style.filter = f1.concat(f2);

if (count > 1)
{ ...

(我希望这是有道理的。导致setTimeout(...)导致该函数的每一行代码都需要时间来执行,这是我的观点。)

如果您的问题仅仅是两个函数的相对时序(而不是5000毫秒永远不会精确到5000毫秒),那么这是一个非常简单的解决方案。

从一个计时器执行所有操作。: - )

创建一个“时钟”,其间隔为所有其他时钟间隔的公共分区。在你的情况下100毫秒是足够的,因为它可以乘以整数到5000毫秒,4000毫秒和100毫秒。

废弃所有其他代码行:

window.onload = setTimeout(Initialize, 0);
window.onload = setInterval(ImageFader, 4000);
window.onload = setInterval(ChangeImage, 5000);

而是计算一个100ms时钟的执行次数。 50次执行该时钟应触发ChangeImage,40次执行应触发ImageFader等。

这将为您提供精确的相对时间。

更新以包含示例伪代码:

var clockCount = 0;
var fading = false;

setTimeout(globalClock, 100);
function globalClock(
   clockCount++;

   if (clockCount == 40) {
      ImageFader();
   } elseif (clockCount == 50) {
      ChangeImage();
   }

   if (fading) {
      Fade();
   }

   // At end of function so we don't ever trigger multiple executions at the same time
   setTimeout(globalClock, 100);
);

答案 1 :(得分:0)

移除setInterval()来电,仅使用setTimeout(),将所有定时器整理到链中:

  1. setTimeout(Fade, 4000)的末尾致电Initialize()

  2. 多次从setTimeout(Fade, 100)本身拨打Fade(),但最后一步是setTimeout(ChangeImage, 100)

  3. setTimeout(Fade, 4000)的末尾致电ChangeImage()

答案 2 :(得分:0)

以下是我使用单独的setInverval()方法解决淡入淡出和图像更改的问题:

window.onload = setTimeout(Initialize, 0);
window.onload = setInterval(ImageFader, 8000);

function Initialize()
{
    image = document.getElementById('title-image');
    image.src = "images/image-1.jpg";
}

function ChangeImage()
{
    image = document.getElementById('title-image');
    do
    {
        num = Math.floor((Math.random() * 10) + 1);
    } while (num == lastNum);
    lastNum = num;
    temp = file.concat(num.toString());
    image.src = temp.concat(ext);
}

function ImageFader()
{
    setTimeout(Fade, 100);
}

function Fade()
{
    tcount = count / 10;
    image.style.opacity = tcount;
    f1 = f1.concat((tcount * 100).toString());
    image.style.filter = f1.concat(f2);

    if (count > 1)
    {
        count--;
        setTimeout(Fade, 100);
    }
    else
    {
        count = 10;
        ChangeImage();
        image.style.opacity = 1;
        image.style.filter = "alpha(opacity=100)";
    }
}