2009-01-14 41 views
9

我有一段jQuery的代码调用快速连续几个getJSON()电话:jQuery的范围或竞争条件

var table = $("table#output"); 
for (var i in items) { 
    var thisItem = items[i]; 
    $.getJSON("myService", { "itemID": thisItem }, function(json) { 
     var str = "<tr>"; 
     str += "<td>" + thisItem + "</td>"; 
     str += "<td>" + json.someMember + "</td>"; 
     str += "</tr>"; 
     table.append(str); 
    }); 
} 

当我跑这对一个laggy服务器,该表获取与填充预计值为json.someMember(它们按顺序到达:我不介意),但thisItem列填充了来自各种迭代的不可预知的混合值。

我假设这是与范围和时间有关 - 回调函数从更广泛的范围读取thisItem?我对吗?我如何防止这种情况?

我目前的解决方法是让JSON服务返回其输入的副本 - 至少令人不满意。

+0

谢谢Slim问这个问题。我也有一些问题(我知道异步函数返回,但不知道如何发信号通知getJSON回调什么位置来放置返回值)。 – 2010-03-01 01:16:11

回答

12

似乎由于循环而导致的范围界定问题。试试这个:

var table = $("table#output"); 
for (var i in items) { 
    var thisItem = items[i]; 
    $.getJSON("myService", { "itemID": thisItem }, (function(thisItem) { 
     return function(json) { 
      var str = "<tr>"; 
      str += "<td>" + thisItem + "</td>"; 
      str += "<td>" + json.someMember + "</td>"; 
      str += "</tr>"; 
      table.append(str); 
     } 
    })(thisItem)); 
} 

编辑:我所做的只是范围thisItem$.getJSON回调。

+0

我不认为这将适用于jQuery。 json最终不会传入闭包而不是thisItem变量并导致错误? – jacobangel 2009-01-14 22:17:55

+1

No. $ .getJSON获取内部函数传递;获取“json”参数的那个。 – 2009-01-14 22:25:51

3

JavaScript不使用范围块。范围仅基于功能。

如果你想要一个新的作用域,你必须声明一个新的内部函数并立即运行它,这是在Javascript中创建一个新作用域的唯一方法。

var table = $("table#output"); 
for(var i in items) 
{ 
    (function(){ 
     var thisItem = items[i]; 
     $.getJSON("myService", { "itemID": thisItem }, function(json) 
     { 
      var str = "<tr>"; 
      str += "<td>" + thisItem + "</td>"; 
      str += "<td>" + json.someMember + "</td>"; 
      str += "</tr>"; 
      table.append(str); 
     }); 
    })(); 
}