2016-08-11 46 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 
    } 

我该怎么做才能解决这个问题?我一直在尝试奇怪的全局变量技巧和各种黑客攻击,但没有任何工作。

UPDATE 我也试图把我的最后两行$.get呼叫,但states[j]是由于某种原因,在循环内无法访问。 经过调试,看起来好像只是j在这个返回函数内部是无法从外部循环访问的。有没有办法解决这个问题?


更新2

我跟着建议在回答给定的,我上午得到正确连接的字符串为fullHTML,每个fullHTML字符串仅更换最后状态在桌子里。就好像TX标签是唯一一个接收所有更新的标签。我认为这是基于封闭的,但我不知道如何解决这个问题。

$(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

这不是_stuck_循环,它关于时间。在数据从服务器加载并分配给变量之前,您正在访问该变量。 **没关系,但如何解决这个问题?**只需移动'$ .get()'回调中的最后一条语句即可。 – Tushar

+0

@Tushar请看我对我的问题的更新,为什么我想这样做,但遇到了问题。 – qarthandso

+0

@qarthandso请参阅我的编辑以获取适用于'Update 2'的工作解决方案。此外,我不知道为什么这被标记为重复(特别是对于这个问题,因为这不是你要求的,但这[先前被问到](http://stackoverflow.com/questions/7053965/when-使用回调 - 在一个循环在JavaScript的是在那里任何方式来保存一个变种)其他地方,但重复没有指向一个相关的问题。) –

回答

2

这是一个异步 $不用彷徨功能。也就是说,代码执行将而不是在该行等待,直到完成$ .get,执行回调函数,然后继续执行$ .get之后的下一行。实际上,它将执行对$ .get函数的异步调用,并立即继续执行至console.log(fullHTML)行。目前还不能保证$ .get函数已经完成甚至开始,因为它正在异步执行。

至于你的问题与j的可访问性,这是一个问题,可以回到关闭。当您在$ .get回调内部访问时,您的j变量将引用已经循环遍历的j变量,并将返回不正确的j值,因为您可能希望从$ .get请求获得值为j执行。因此,您需要在本地关闭中存储j,方法是将其明确地声明为var current = j,而不是在$ .get回调中引用j,您将参考current,它将按预期执行。这不起作用!

编辑

我们可以强制创建一个新的范围,如果我们声明一个匿名函数并执行这方面的内部$不用彷徨。这不是一个漂亮的解决方案,但它的工作原理!

要修复您的代码,请将您的呼叫放入$中。得到回调,像这样:

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是必需的?存储当前的“状态”值? – qarthandso