web-dev-qa-db-ja.com

JSでのタイミング-複数のsetIntervalsが一度に実行され、同時に開始されますか?

関数があるとしましょう:

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

そして、設定した間隔で実行するようにします。 setInterval を使用する必要があるようですね。

しかし、同じ機能の複数の間隔を実行し、すべてがまったく同時に開始する場合はどうでしょうか?

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

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

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

そのため、最初の実行は2番目の実行に1回かかるのに正確に2回実行され、2番目と3番目の間は同じになります。

それらが同期するように、それらがすべて同時に開始することをどのように確認しますか?

21
Joshua Soileau

良い質問ですが、JSではできません。同じプログラム内で複数の機能を同時に実行するには、マルチスレッドと、深いタイミングとスレッド処理のスキルが必要です。 JSはシングルスレッドです。 setIntervalは遅延後に関数を実際に実行するのではなく、遅延後に関数がイベントスタックに追加され、プロセッサが到達するとすぐに実行されます。 procが別の操作でビジーの場合、実際に実行するのに遅延期間よりも長くかかります。複数の間隔/タイムアウトはすべて同じイベントスタックに呼び出しを追加するため、プロシージャが使用可能になると順番に実行されます。

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

有限数のティックの場合、最後のパラメーターをnumberの正の整数に変更します。連続実行を示すために-1を使用しました。

あなたにはできないと言っている人は無視してください。あなたが好きなことなら何でもできます!

6
user5078091

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
Alex Shilman

このようなものを作ることができます。

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

それが役に立てば幸い!

2
Bartuken