Сроки в JS - несколько setIntervals запускаются одновременно и начинаются в одно и то же время?

Скажем, у меня есть функция:

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

И я хочу, чтобы он работал на заданном интервале. Похоже, я должен использовать setInterval, huh!

Но что, если я хочу запустить несколько интервалов одной и той же функции, все началось с того же самого времени?

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

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

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

Так, чтобы первый выполнялся ровно дважды за время, за которое секунда запускалась один раз, и то же самое между вторым и третьим.

Как вы убедитесь, что все они запускаются одновременно, чтобы они синхронизировались?

Ответы

Ответ 1

Хороший вопрос, но в JS вы не можете. Для одновременного выполнения нескольких функций в одной и той же программе вам понадобятся многопоточность и некоторые глубокие навыки обработки времени и потоков. JS однопоточный. setInterval не активирует функцию после задержки, а после задержки добавляет функцию к стеку событий, который должен быть запущен, как только процессор сможет добраться до него. Если proc занят другой операцией, для фактического запуска потребуется больше времени задержки. Множественные интервалы/таймауты все добавляют вызовы к одному стеклу событий, поэтому они запускаются поочередно, когда доступен proc.

Ответ 2

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 для индикации непрерывной работы.

Игнорировать любого, кто говорит вам, что вы не можете. Вы можете сделать все, что угодно!

Ответ 3

JavaScript однопоточный. Вы можете использовать веб-рабочий html5 или рекурсивно использовать 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

Ответ 4

Вы можете сделать что-то вроде этого.

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));

Надеюсь, что это поможет!

Ответ 5

Это довольно изящно, но как вы это зациклите (вместо того, чтобы делать setTimer0 =, setTimer1 =,...)?