Domanda

Ho un pezzo di codice jQuery che invoca diverse chiamate getJSON () in rapida successione:

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

Quando eseguo questo su un server ritardato, la tabella viene popolata con i valori previsti json.someMember (arrivano fuori servizio: non mi dispiace), ma il thisItem è popolato con una miscela imprevedibile di valori da varie iterazioni.

Suppongo che ciò abbia a che fare con l'ambito e i tempi: la funzione di callback sta leggendo thisItem da un ambito più ampio? Ho ragione? Come posso impedirlo?

La mia attuale soluzione alternativa è che il servizio JSON restituisca una copia dei suoi input, il che è insoddisfacente per non dire altro.

È stato utile?

Soluzione

Sembra un problema di scoping dovuto al loop. Prova questo:

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

Modifica : tutto quello che ho fatto è stato ambito thisItem sul callback $ .getJSON .

Altri suggerimenti

Javascript non utilizza il blocco per ambito. L'ambito si basa solo sulle funzioni.

Se si desidera un nuovo ambito, è necessario dichiarare una nuova funzione interna ed eseguirla immediatamente, questo è l'unico modo per creare un nuovo ambito in 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);
        });
    })();
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top