2009-01-14 78 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); 
     }); 
    })(); 
}