web-dev-qa-db-ja.com

forループ内でsetInterval関数を使用する方法

アイテムの可変リストを指定して、複数のタイマーを実行しようとしています。コードは次のようになります。

var list = Array(...);

for(var x in list){
    setInterval(function(){
        list[x] += 10;
        console.log(x + "=>" + list[x] + "\n");
    }, 5 * 1000);
}

上記のコードの問題は、更新される唯一の値がリストの最後のアイテムにリスト内のアイテムの数を掛けたものであるということです。

誰もが解決策といくつかの説明を提供できますか?

29
hyleaus

だから、いくつかのこと:

  1. 最も重要なこととして、setInterval()に渡したコールバック関数は、特定の反復中に存在したxのスナップショット値ではなく、xへの参照を維持します。したがって、ループ内でxが変更されると、各コールバック関数内でも更新されます。
  2. さらに、 _for...in_ はオブジェクトのプロパティを列挙するために使用され、配列で使用される場合は 予期しない動作 が可能です。
  3. さらに、 setTimeout() ではなく setInterval() が本当に必要だと思います。

setTimout()に追加の引数を指定することにより、コールバック関数に引数を渡すことができます。

var timeoutID = window.setTimeout(func, delay, [param1, param2, ...]);

数値は参照ではなく値で渡されます。次に例を示します。

_var list = [1,2,3,4];

for (var x = 0, ln = list.length; x < ln; x++) {
  setTimeout(function(y) {    
    console.log("%d => %d", y, list[y] += 10);
  }, x * 500, x); // we're passing x
}_
38
canon
var list = [1, 2, 3, 4, 5];

for (var i = 0, len = list.length; i < len; i += 1) {
    (function(i) {
        setInterval(function() {
            list[i] += 10;
            console.log(i + "=>" + list[i] + "\n");
        }, 5000)
    })(i);
}

作業コードは次のとおりです。

var list = [1, 2, 3, 4, 5];

for (var i = 0, len = list.length; i < len; i += 1) {
    (function(i) {
        setInterval(function() {
            list[i] += 10;
            console.log(i + "=>" + list[i] + "\n");
        }, 5000)
    })(i);
}

ここでは、インデックスiは匿名関数に格納されているため、連続したループで上書きされません。コード内のsetInterval関数は、iの最後の値への参照のみを保持します。

39
Lapple

setIntervalステートメントでforサイクルを使用する必要はありません。これを試して:

var list = Array(...);
var x = 0;

setInterval(function() {

    if (x < list.length;) {
        list[x] += 10;
        console.log(x+"=>"+list[x]);
    }

    else return;

    x++;
}, 5000);
4
uncleJessie

Forループでこれを行う方法はわかりませんが、このコードは、配列内の各要素を一定の間隔で出力します。

function displayText(str) {
   $('.demo').append($('<div>').text(str));
}
var i = 0;

var a = [12, 3, 45, 6, 7, 10];

function timedLoop() {
setTimeout(function () {
    displayText(a[i]);
    i++;
    if(i < a.length) {
        timedLoop();
    }
}, 2000)
}

timedLoop();

少しのjqueryを使用してブラウザに表示します。

2
Ryan Mc

JSON配列とjQueryが含まれている場合は、次を使用できます。

$.each(jsonArray, function(i, obj) {
    setInterval( function() {
        console.log(i+' '+obj);
    }, 10);
});
0
Atul Yadav

forEachsetTimeoutを組み合わせて、間隔のある配列をループできます。

let modes = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let interval = 1000; //one second
modes.forEach((mode, index) => {

  setTimeout(() => {
    console.log(mode)
  }, index * interval)
})
0
Taha A.