Область jQuery или условие гонки в AJAX / getJSON - PullRequest
9 голосов
/ 15 января 2009

У меня есть фрагмент кода 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 возвращает копию своих входных данных, что, по меньшей мере, неудовлетворительно.

Ответы [ 2 ]

12 голосов
/ 15 января 2009

Похоже, проблема с областью видимости из-за цикла. Попробуйте это:

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.

3 голосов
/ 15 января 2009

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);
        });
    })();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...