Javascript反復リスト操作でsetTimeoutを使用する方法は?

私はこのようなことをしたい:

for(var i=0;i

もちろん、javascriptにはスリープ機能はありませんので、私は次のことを試しました:

for(var i=0;i

しかし、aList [i]は定義されていません。無名関数はクロージャであるため、実際にはaList [i]を外部関数のスコープから読み込んでいるため、setTimeoutの関数が実行されるまでに i は既に変更されています。

これを達成する方法は何ですか?

0

5 答え

JavaScript 1.7の let をエミュレートするクイックフィックスは、関数内にラップすることです。

for(var i=0; i < aList.length; i++) {
    (function(i) {
        setTimeout(function() {
            aList[i].doSomething();
        }, 500 * i);//<-- You need to multiply by i here.
    })(i);
}

また、スクリプトが500秒間ポーズした後、すべてを実行する小さなバグに修正を加えました。 setTimeout は非ブロックです。

6
追加された

これはおそらくあなたが望むものです:

for(var i=0;i

500 * i は、各ステップが最後のステップより500ms後になるようにします。そうしないと、500ms後にすべてが一気に実行されます。余分なラッピング関数に注目してください。これは本質的に i の値をトラップ/保持します。

4
追加された
@minitech、ありがとう、しかし、FYI、それは何の違いはありません。 AFAIK、それは好みの問題です。
追加された 著者 James,

バリアントの1つ:

var array = [/*elements*/],
    i,
    length = array.length,
    loop = setInterval(function() {
        array[i].doSomething();
        i += 1;
        if (i === length) {
            clearInterval(loop);
        }
    }, 500);
1
追加された

タイムアウトの前に関数を定義するだけです

for(var i=0; nextFunction = aList[i];i++) {
    var waitAndDoSomething = function(func) {
        return function() { func.doSomething(); }
    };
    setTimeout(waitAndDoSomething(nextFunction),500*i);  
}

もう一つの可能​​な答え

At minitect's suggestion, I started to think about other possible solutions. A solution that I feel comes out clean is to use bind

String.prototype.doSomething = function() { alert(this); }//Just for testing
var aList = ['one', 'two', 'three'];//Just for testing

for(var i=0;obj = aList[i];i++) { 
    setTimeout(obj.doSomething.bind(obj),500*i); 
}

しかし、私はaList [i]がどのように表現するのか分からないので、これがRazor Stormの質問の文脈でどれほどうまくいくかはわかりません。

これは質問に答えますか?

これが意図された動作であるかどうかも疑問です。実行後に実際にスリープするのではなく、むしろタイミングを設定します。これは欺かれているかもしれませんが、実際に関数を実行してから次の1秒前に睡眠を取る場合は、ここでタイミングが外れています。代わりに再帰を使用します。

String.prototype.doSomething = function() { alert(this); }
var aList = ['one', 'two', 'three'];

var doNextSomething = function(index) {
    if (!index) { index = 0 }
    if (nextObject = aList[index]) {
        nextObject.doSomething();
        setTimeout(doNextSomething, 500, index + 1);    
    }
};

doNextSomething();

これで、関数が実行されてから500ミリ秒待機します(長い実行中のタスクでは明らかです)。

投稿された回答は、Razor Stormが気にしていたものよりも多かったと思います。

1
追加された
JavaScriptは関数スコープ以外のスコープがないため、実際には動作しません。 nextFunction は再定義されます。 jsfiddle.net/N9LBU また、あなたは * i の問題を修正しませんでした。 -1
追加された 著者 Ry-,
まあ、あなたはまだあなたのポストでそれを修正することができます - 投票は柔軟性があります。
追加された 著者 Ry-,
@minitech - 私は訂正した。
追加された 著者 natedavisolds,
@minitech私は自分の答えを編集し、さらに2つを追加しました。
追加された 著者 natedavisolds,

forループの前に何かする:

var _aList = aList;

ループ内では、setTimeoutとdelay 500 * iを設定する必要があります。

結果は次のようになります。

var _aList = aList;
for(var i=0;i
0
追加された
JavaScript - 日本のコミュニティ
JavaScript - 日本のコミュニティ
2 参加者の

日本人コミュニティのjavascript