2017-01-19 13 views
0

私は以下のような配列を持っています。Javascriptの閉鎖は

var clients = ['a','b']; 
var reports = ['x','y','z']; 
var finalData = []; 

これでこのようなループが必要です。

for(var i=0;i<reports.length;i++){ 
    var response = {report : reports[i]} 
    for(var j=0;j<clients;j++){ 
     response.client = clients[i]; 
     $.ajax({ 
     url :url, 
     success : function(data){ 
      response.data = data; 
      finalData.push(response); 
     }) 
    }); 
    } 
} 

ajaxは非同期であるため、正しく動作しません。 また、これをreact.jsのcomponentDidMount関数にラップし、finalDataを状態にプッシュする必要があります。

私はループの代わりに$.eachを試して、最終データを状態にプッシュするには.bind(this)を試しました。しかし、私は正しいデータを取得しませんでした。非同期呼び出しのクロージャが使用されるべきだと聞きましたが、ここでどのように実装されるのかは分かりません。 私が探している出力はです。

あなたが次のことを試して、あなたの応答変数のスコープ(使用colsure)を保存する必要が
finalData = [ 
     {client:a,report:x,data : 'xyz'}, 
     {client:b,report:x,data : 'xyz'}, 
     {client:a,report:y,data : 'xyz'}, 
     {client:b,report:y,data : 'xyz'}, 
     {client:a,report:z,data : 'xyz'}, 
     {client:b,report:z,data : 'xyz'} 
    ] 
+1

あなたは詳細のためにこれを見レポートや顧客価値を維持するためにクロージャを使用することができhttp://stackoverflow.com/questions/6077357/passing-index-from-for-loop-to-ajax-callback-function-javascript –

+0

サンプルコードに複数のコーディングエラーがあります。例えば'clients [i]'は 'clients [j]'でなければなりません。 –

答えて

0

for(var i=0;i<reports.length;i++){ 
    var response = {report : reports[i]} 
    for(var j=0;j<clients;j++){ 
     response.client = clients[i]; 

     (function(responce){ 
     $.ajax({ 
     url :url, 
     success : function(data){ 
      response.data = data; 
      finalData.push(response); 
     }) 
     })(responce); 

    }); 
    } 
} 

はのは、AJAXを例にここsetTimeoutを使用しますシミュレートするために、より多くのそれを説明しましょう:

この例を考えてみましょう。ループを5回、1秒後に印刷する必要があります。i 0 1 2 3 4を印刷することを期待していますが、実際には5回5回印刷します。秒消費し、それが海のとき私はこのケース= 5

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

に私を印刷すると、それが呼ばれて、私のために正しい値を見つけることができたときにタイムアウト仕上げているので、私のために値を保存するためのスコープを持っている必要があります解決するためのRCH終了:

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

このコードは期待どおりに機能し、0 1 2 3 4が正しく表示されます。これはあなたの例で行ったことです。

と状態を更新するために、あなたはそれをあなたのように値を受け取るたびに更新することができ、次のいずれか

var that = this; // to be added in top of the 2 for loops 
finalData.push(response); 
this.setState({data: finalData}) 

かあなたはすべてのレポートは、すべてのクライアントのためにロードされているかどうかをチェックして、状態を更新することができます

// total can be calculated by num of reports X number of clients 
if(finalData.length == total){ 
    this.setState({data: finalData}) 
}