1

配列を繰り返し処理し、要素ごとに、コールバックを呼び出す何かを実行しています。私の問題は、コールバック内で、反復のどのパスにあるかを知る必要があることです。

簡略化すると、私のコードは次のようになります...

for (var i=0; i<3; i++ {
  setTimeout(function () {
      console.log(i);
  },1000);
}

そして、私は見たいです

0
1
2

私が得ているのは

3
3
3

3 を取得する理由は理解できますが、0,1,2 を取得する方法がわかりません

注意。これは私の問題の簡略版です。myapp では、実際にストレージ操作を呼び出しているため、コールバック関数の引数として単純に "i" を指定することはできません。

4

2 に答える 2

5

JSには関数スコープがあるため、反復時に値をキャプチャする必要があるため、i参照するのと同じです.(そしてそれは望ましくありません。したがって、クロージャーを作成する必要があります.

for (var i = 0; i < 3; i++) {
    (function (a) {
        setTimeout(function () {
            console.log(a);
        }, 1000);
    })(i);
}
于 2013-10-10T16:26:00.773 に答える
1

isettimeout が非同期であり、 forloop と set timeout 関数の両方が同じ変数を共有しているため、 3になっているのはなぜですかi。これは、コールバックが呼び出される前に for ループが完全に実行されることを意味します3。したがって、回避策は、変数のローカルスコープを作成するか、つまりクロージャーを作成することです。

for (var i=0; i<3; i++) {
   (function(iter){ //Now with this you are creating a local closure for the variable iter and each setTimeout instance will no longer share the variable `i` instead it will use the variable created in its own scope defined by the anonymous function.
     setTimeout(function () {
         console.log(iter);
     },1000);
   })(i)
}
于 2013-10-10T16:28:27.717 に答える