JS中的计时 - 多个setIntervals同时运行并同时启动?

时间:2013-12-04 02:59:12

标签: javascript jquery intervals timing

假设我有一个功能:

myFunc = function(number) {
  console.log("Booyah! "+number);
}

我希望它在设定的时间间隔内运行。听起来我应该使用setInterval,呵呵!

但是,如果我想运行相同功能的多个时间间隔,所有时间都从同一时间开始呢?

setInterval(function(){
  myFunc(1);
}, 500);

setInterval(function(){
  myFunc(2);
}, 1000);

setInterval(function(){
  myFunc(3);
}, 2000);

因此,第一个运行的时间恰好是第二次运行一次,而第二次和第三次之间运行时间相同。

如何确保它们全部同时启动以便它们同步?

5 个答案:

答案 0 :(得分:21)

很好的问题,但在JS中你不能。要在同一程序中执行多个功能,您需要同时执行多线程和一些深度计时和线程处理技能。 JS是单线程的。 setInterval在延迟之后没有实际运行该函数,而是在延迟之后它将函数添加到事件堆栈以便在处理器可以运行时立即运行。如果proc忙于另一个操作,则实际运行所需的时间将比延迟时间长。多个间隔/超时都会添加对同一事件堆栈的调用,因此它们会在proc可用时依次运行。

答案 1 :(得分:5)

function Timer(funct, delayMs, times)
{
  if(times==undefined)
  {
    times=-1;
  }
  if(delayMs==undefined)
  {
    delayMs=10;
  }
  this.funct=funct;
  var times=times;
  var timesCount=0;
  var ticks = (delayMs/10)|0;
  var count=0;
  Timer.instances.push(this);

  this.tick = function()
  {
    if(count>=ticks)
    {
      this.funct();
      count=0;
      if(times>-1)
      {
        timesCount++;
        if(timesCount>=times)
        {
          this.stop();
        }
      }
    }
    count++; 
  };

  this.stop=function()
  {
    var index = Timer.instances.indexOf(this);
    Timer.instances.splice(index, 1);
  };
}

Timer.instances=[];

Timer.ontick=function()
{
  for(var i in Timer.instances)
  {
    Timer.instances[i].tick();
  }
};

window.setInterval(Timer.ontick, 10);

使用它:

function onTick()
{
  window.alert('test');
}
function onTick2()
{
  window.alert('test2');
}
var timer = new Timer(onTick, 2000,-1);
var timer = new Timer(onTick2, 16000,-1);

对于有限数量的刻度,将最后一个参数更改为数字的正整数。我使用-1表示连续运行。

忽略任何告诉你无法做到的人。你可以做任何你喜欢的事情!

答案 2 :(得分:3)

JavaScript是单线程的。您可以使用html5 web worker或尝试递归使用setTimeout。按照此示例创建多个函数:

var interval = setTimeout(appendDateToBody, 5000);

function appendDateToBody() {
    document.body.appendChild(
        document.createTextNode(new Date() + " "));
    interval = setTimeout(appendDateToBody, 5000);
}

阅读这篇文章:

http://weblogs.asp.net/bleroy/archive/2009/05/14/setinterval-is-moderately-evil.aspx

答案 3 :(得分:2)

You can make something like this.

arr = Array();
arr[0] = "hi";
arr[1] = "bye";
setTimer0 = setInterval(function(id){
  console.log(arr[id])
},1000,(0));

setTimer1 = setInterval(function(id){
  console.log(arr[id]);
},500,(1));

Hope it helps!

答案 4 :(得分:0)

您可以在函数内部使用多个刻度,在下面的示例中,您可以每0.1秒运行一个函数,而每1秒运行另一个函数。 显然,如果功能所需的时间比您设置的时间间隔长,则计时会出错。您可能需要尝试使用这些值,以使其起作用或容忍错误的时间安排。

设置变量以处理刻度倍数

let tickDivider = -1

在更快的函数中增加tick变量的值

const fastFunc = ()=> {
    tickDivider += 1
    console.log('fastFunciton')
    }

使用条件来运行慢速功能

const slowFunc = ()=> {
            if (!(tickDivider % 10)){
                console.log('slowFunction')
            }
}

一次调用两个函数。除非您将tickDivider设置为0(10的任意倍数),否则顺序并不重要

const updateAllFuncs = () => {
    fastFunc()
    slowFunc()
}

将间隔设置为更快功能的频率

setInterval(updateAllFuncs, 100)