2016-08-11 4 views
2

私は特定の状態のすべてのストアを取得するためにAJAX呼び出しを行っています。問題は、最後の2行はgetコールからの返信関数で構築した変数コンテンツにアクセスできないということです。JavaScriptの変数がループ内でスタックしています - アクセスできない

var states = ['TX', 'AZ]; 

    for(j = 0; j < states.length; j++) { 
     var fullHTML = ''; 
     var full2; 
     $.get("//127.0.0.1:8000/api/state-stores/", {state: states[j]}, function(data) { 
      console.log(data.stores.length); 

      for(var i = 0; i < data.stores.length; i++) { 
       store_html = '<tr><td>' + data.stores[i].name + '</td><td>' 
       fullHTML += store_html; 
      } 
     }) 
     // PROBLEM HERE 
     console.log(fullHTML); //empty 
     $("#" + states[j].toLowerCase() + "-table").html(fullHTML); //does nothing 
    } 

これを修正するにはどうすればよいですか?私は奇妙なグローバル変数のトリックやハックyのすべての種類のものを試してきましたが、何も動作していません。

UPDATE 私も内部$.getコール私の最後の2行を配置しようとしたが、states[j]は、ループ内でアクセスできない何らかの理由です。 デバッグ後、この戻り関数内では外側ループからのjがアクセス不能になったようです。それを修正する方法はありますか?


UPDATE 2

私は答えで与えられたアドバイスに従って、私はは、fullHTMLしかしため、正しく連結された文字列を取得しています各fullHTML文字列のみ最後状態を交換していますテーブルにこれは、あたかもTXタグがすべての更新を受信して​​いるかのようです。私はこれが閉鎖に基づいていると思うが、私はこれを解決する方法を知らない。

非同期 $に.get機能です
$(function() { 
    var states = ['AZ', 'CA', 'CO', 'GA', 'NV', 'NC', 'SC', 'TX']; 
    // var states = ['CA']; 
    for(var j = 0; j < states.length; j++) { 
     var current = j; 
     $.get("//127.0.0.1:8000/api/state-stores/", {state: states[j]}, function(data) { 
      var fullHTML = ''; 
      for(var i = 0; i < data.stores.length; i++) { 
       store_html = '<tr><td>' + data.stores[i].name + '</td><td>' + data.stores[i].address + '<span class="small-table"><br>' + data.stores[i].city + '</span></td><td>' + data.stores[i].city + '</td><td>' + data.stores[i].state + '</td><td>' + data.stores[i].postal_code + '</td></tr>' 
       fullHTML += store_html; 
      } 
      $('#' + states[current].toLowerCase() + '-table').html(fullHTML); 
     }) 
    } 

}); 
+2

ループの中には止まっていません。変数は、サーバーからデータをロードして変数に割り当てる前に変数にアクセスしています。 **これは問題ですが、これを解決する方法は?**最後の文を '$ .get()'コールバックの中に移動するだけです。 – Tushar

+0

@ Tusharなぜ私はこのようにしたいのですか?私の質問に私の更新を見てくださいが、問題に遭遇しました。 – qarthandso

+0

@karthandsoあなたの 'Update 2'への働く解決策について私の編集を見てください。また、私はなぜこれが重複としてマークされているのか分かりません(特に、その質問には、あなたが求めていたものではありませんが、これは以前に尋ねられました)(http://stackoverflow.com/questions/7053965/when-他の場所でコールバックを使用してループ内でループを使用していますが、複製は関連する質問を指していません) –

答えて

2

。つまり、コード実行はで、は$ .getが完了するまでその行で待機し、コールバック関数を実行して$ .getの後の次の行に進みます。実際には、$ .get関数への非同期呼び出しを実行し、すぐにconsole.log(fullHTML)行への実行を続行します。現時点では、$ .get関数が非同期に実行されているので、$ .get関数が終了しているか、または開始されているという保証はありません。

jへのアクセシビリティに関する問題は、閉鎖に戻ってくる問題です。あなたのj変数は、$に.getコールバックの内側にアクセスしたときに、すでにループスルーされたj変数を参照します、とあなたはおそらく$に.get要求だったときからjの値をしたいと、間違ったj値を返します。実行される。したがって、jをローカルクロージャの内側に格納する場合は、var current = jのように明示的に宣言し、$ .getコールバック内にjを参照するのではなく、currentを参照し、意図した通りに動作します。これは動作しません!

EDIT

私たちは、匿名関数を宣言する場合は、新しいスコープを作成して強制し、そのコンテキスト内の$に.getを実行することができます。それはかなりの解決策ではありませんが、機能します!あなたのコードを修正するには

は、$の内側にあなたの電話を入れました。そのようにコールバックを取得:

var states = ['TX', 'AZ']; 

for(j = 0; j < states.length; j++) { 
    var fullHTML = ''; 
    var full2; 
    (function() { 
     var current = j; 
     $.get("//127.0.0.1:8000/api/state-stores/", {state: states[j]}, function(data) { 
      console.log(data.stores.length); 

      for(var i = 0; i < data.stores.length; i++) { 
       store_html = '<tr><td>' + data.stores[i].name + '</td><td>' 
       fullHTML += store_html; 
      } 
      console.log(fullHTML); // not empty anymore 
      $("#" + states[current].toLowerCase() + "-table").html(fullHTML); //does stuff 
     }); 
    })(); 
} 

今、あなたのコードは唯一それがfullHTML変数を埋めた後にする前に破壊された行を実行します。

+0

私はしたいこのようにするだけでなく、問題に遭遇しました。この方法が私にとってうまくいかなかった理由についての私の更新された質問を見てください。 – qarthandso

+0

@ qarthandsoそれに対処するために私の答えを更新しました。 –

+0

これは正確な解決策です。どうもありがとうございます。このIIFEはなぜ必要なのですか?現在の 'state'値を保存するには? – qarthandso

関連する問題