代码之家  ›  专栏  ›  技术社区  ›  slim

AJAX/getJSON中的jQuery作用域或竞争条件

  •  9
  • slim  · 技术社区  · 16 年前

    我有一段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 列中填充了来自各种迭代的不可预测的混合值。

    我假设这与作用域和时间有关——回调函数正在读取 此项目 从更广泛的范围?我说的对吗?我该如何防止这种情况?

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

    2 回复  |  直到 16 年前
        1
  •  12
  •   Crescent Fresh    16 年前

    由于循环,这似乎是一个范围界定问题。试试这个:

    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 回拨。

        2
  •  3
  •   Vincent Robert    16 年前

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