Синхронизация в JS-несколько setIntervals работает одновременно и начинается одновременно?

Допустим у меня есть функция:

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

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

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

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

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

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

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

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

4 ответов


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


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 для обозначения непрерывного выполнения.

игнорируйте любого, кто говорит вам, что вы не можете. Ты можешь заставить его делать все, что захочешь!


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


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

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

надеюсь, что это помогает!