javascript - consulta - ajax sincrono jquery
Alcance jQuery o condiciĆ³n de carrera en AJAX/getJSON (2)
Tengo un fragmento de código jQuery que invoca varias llamadas a getJSON()
en rápida sucesión:
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);
});
}
Cuando ejecuto esto en un servidor laggy, la tabla se llena con los valores json.someMember
esperados (llegan fuera de orden: no me importa), pero la columna thisItem
está poblada con una mezcla impredecible de valores de varias iteraciones .
Supongo que esto tiene algo que ver con el alcance y el tiempo: ¿la función de devolución de llamada está leyendo este thisItem
desde un alcance más amplio? ¿Estoy en lo cierto? ¿Cómo evito esto?
Mi solución actual es que el servicio JSON devuelva una copia de sus entradas, lo que es insatisfactorio por decir lo menos.
Javascript no usa el bloque para el alcance. El alcance solo se basa en funciones.
Si desea un nuevo ámbito, debe declarar una nueva función interna y ejecutarla de inmediato, esta es la única forma de crear un nuevo ámbito en 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);
});
})();
}
Parece un problema de alcance debido al ciclo. Prueba esto:
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));
}
Editar : todo lo que hice fue thisItem
a la devolución de llamada $.getJSON
.