2017-06-01 10 views
0

私はカウントダウンタイマーを作っています。私がsetInterval()関数を取り出し、一時停止せずに時間を減らすと、プログラムは正しく動作します。setInterval timer function not working

しかし、setInterval()関数を使用して毎秒だけ時間を減らすコードを呼び出すと、プログラムがハングします。

function timeControl() { 
    var minutesLeft = $('#minutes').text(); 
    var secondsLeft = $('#seconds').text(); 

    while(Number(minutesLeft) > 0 || Number(secondsLeft) > 0) { 
     window.setInterval(decreaseTime, 1000); 

     minutesLeft = $('#minutes').text(); 
     secondsLeft = $('#seconds').text(); 
    } 
} 


function decreaseTime() { 
    var secondsLeft = $('#seconds').text(); 
    var minutesLeft = $('#minutes').text(); 
    if((Number(minutesLeft) > 0) && (Number(secondsLeft) == 0)) { 
    $('#minutes').text(Number(minutesLeft) - 1); 
    $('#seconds').text(4); 
    } else { 
     $('#seconds').text(Number(secondsLeft) - 1); 
    } 
} 
+2

'setInterval'は非同期なので、あなたのコードは要素を更新していないので、無限ループになります。 –

+1

これはあなたが 'setInterval()'を使う方法ではありません。スケジュールされているものに依存する 'while'ループはありません。終了することはありません。 –

+2

[なぜsetIntervalが無限ループになるのですか?](https://stackoverflow.com/questions/37200897/why-is-setinterval-making-infinite-loops) –

答えて

2

あなたはwhileを追加し、それは非常に高速ループので、あなたsetInterval()は何度も呼び出すので、ブラウザがハング。あなたは、setIntervalの第2パラメータで定義されるたびにsetIntervalが実行されるので、中にする必要はありません。あなたは、次のコードを使用することができます

var decreaseTimeInterval; 
function timeControl() { 
    decreaseTimeInterval = window.setInterval(decreaseTime, 1000); 
} 

function decreaseTime() { 
    var secondsLeft = $('#seconds').text(); 
    var minutesLeft = $('#minutes').text(); 
    if((Number(minutesLeft) > 0) && (Number(secondsLeft) == 0)) { 
     $('#minutes').text(Number(minutesLeft) - 1); 
     $('#seconds').text(4); 
    } else if(Number(minutesLeft) == 0 && Number(secondsLeft) == 0) { //end of script 
     clearInterval(decreaseTimeInterval); //clear interval to prevent do again 
    } else { 
     $('#seconds').text(Number(secondsLeft) - 1); 
    } 
} 
1

あなたは機能の同期sleep種類と非同期setInterval機能をconflatingように見えます。彼らは全く異なっている。 setInterval関数はタイマーを設定します。それは、 "関数xをyミリ秒ごとに実行する"と言います。しかし、ここでは、ループ中にその関数を別の時間に設定しています。基本的には、プログラムがハングアップするまで、1秒ごとにdecreaseTime関数を実行するタイマー、数百または数千のタイマーがますます多く設定されます。

あなたのやりたいことは、プログラムのトップレベルにsetInterval関数を置き、1000msごとにtimeControl関数を実行させることです。 timeControl関数からwhileループを削除します。setInterval関数自体がループを実行しているので、不要です。ただし、戻り値がsetIntervalに保存されている必要があります。これにより、停止条件に達したときに変数をクリアできるようになります。要するに、setIntervalについてもっと読む:それはsleepとはまったく異なる概念です。