2011-08-08 15 views
9

私は、ループからjQueryを使用して、いくつかの結果をサーバから取得しています。私はコールバックに固定パラメータとしてループインデックスを含めるが、それが動作しないようにしたい。 forループ内のクロージャ - パラメータとしてループ変数を持つコールバック

(私はそれを行う方法について this articleの助言に従った。)

しかし、私はコールバックに入る値は、私が期待するものは完全ではありません - むしろ、各ループのインデックス値よりも、それは常に同じですインデックスの終了値に設定します。

ie。ここのコードフラグメントはコールバックの実行ごとに '16'を出力します。 1、2、3を印刷するにはどうすればいいですか?(注文が異なるかもしれませんが、それは問題ありません)

以下のコードに加えて、私はいくつかの方法でコールバック関数例えば、 function(data, textStatus) { return test(data, textStatus, idx); }, 'text');など

これはどのように動作するはずですか?

function test(data, textStatus, siteNo) 
{ 
    console.log("siteNo=" + siteNo); 
} 

function loadConfigLists() 
{ 
    var siteReport; 
    // retrieve site configuration 
    jQuery.get("svGetSiteConfig.php", function(data, textStatus)  
    { 
     // retrieve port configuration for all sites 
     for (var idx=1; idx<=15; idx++) 
     { 
      var probeIP = siteConfigArray[idx].siteIP; 
      if (probeIP != "" && probeIP != null) 
      jQuery.get("svGetPortInfo.php?svSiteIpAddr=" + probeIP+"&s="+idx,  
        function(data, textStatus) { test(data, textStatus, idx); }, 'text');  
      else // IP value is blank 
       siteConfigArray[idx].portManifest = null; 
     } 
     } 
    }, 'text');  
} 

答えて

29

これはクロージャでは非常に標準的な問題です。これを行うと:あなたはidxへの参照を結合している

function(data, textStatus) { test(data, textStatus, idx); } 

なくidxの値に設定します。したがって、コールバックが呼び出されるまでに、ループは終了し、バインドしたすべてのコールバックでidxが16になります。

通常のソリューションは、関数呼び出しを通じてidxの評価を強制することです:

function build_callback(idx) { 
    return function(data, textStatus) { 
     test(data, textStatus, idx); 
    }; 
} 

// And then... 

jQuery.get("svGetPortInfo.php?svSiteIpAddr=" + probeIP+"&s="+idx, build_callback(idx), 'text'); 

あなたはそれをすべて一緒に保存しておきたい場合は、自己実行機能を持つ関数をインライン化することができます

for (var idx=1; idx<=15; idx++) 
    (function(idx) { 
     var probeIP = siteConfigArray[idx].siteIP; 
     if (probeIP != "" && probeIP != null) 
      jQuery.get("svGetPortInfo.php?svSiteIpAddr=" + probeIP+"&s="+idx, 
       function(data, textStatus) { test(data, textStatus, idx); }, 'text'); 
     else // IP value is blank 
      siteConfigArray[idx].portManifest = null; 
    })(idx); 

ファンクションコールは、ファンクションがコールされたときにidxという値を返します。値はidxです。

+0

ありがとうございます!それがそれでした。 – Danny

+0

賢い! ........... :-) – TMS

+0

ありがとう、私は、より便利な方法は、すべての関数を変えることです{var {}を使用してblahblah}(function(ii){return function(){古いコードを変更するが、iを "ii"に変更する}}})(i); –

関連する問題