9

我有一段 jQuery 代码可以getJSON()快速连续调用多个调用:

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);
    });
}

当我在一个滞后的服务器上运行它时,表中填充了预期json.someMember值(它们乱序到达:我不介意),但是该thisItem列填充了来自各种迭代的不可预测的混合值。

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

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

4

2 回答 2

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范围。

于 2009-01-14T22:11:27.823 回答
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);
        });
    })();
}
于 2009-01-14T23:14:45.433 回答