2010-03-08 10 views
15

Necesito obtener un rango de páginas usando AJAX y ponerlas en una matriz, donde su lugar dado en la matriz es igual al i de un ciclo for (es una función de almacenamiento en caché para páginas de blog, y el rango del bucle for es completamente variable). Estoy haciendo algo parecido a lo siguiente:AJAX call in for loop no devolverá valores para corregir las posiciones de la matriz

var bongo = new Array(); 

for (i = 0; i < 10; i++) { 

    jQuery.ajax({ type: "GET", url: 'http://localhost', data: queryString, success: function(request) { bongo[i] = request } }) 

} 

El problema es que a menos que agrego async: false a las opciones .ajax (lo que haría ... SJAX?), Lo que hace que las peticiones a básicamente pausa el navegador, yendo en contra de lo que estoy tratando de hacer, el i en la devolución de llamada de éxito siempre terminará siendo 11, mientras que, por supuesto, quiero que vierta los datos devueltos en cada ranura de la matriz de 0 a 10.

he intentado reemplazar la línea con esto:

bongo[i] = jQuery.ajax({ type: "GET", url: 'http://localhost', data: queryString }).responseText 

Pero eso no hizo diferencia.

Respuesta

38

Se necesita un cierre:

var bongo = []; 
for (i = 0; i < 10; i++) 
{ 

    (function(i) 
    { 
     jQuery.ajax(
     { 
      type: "GET", 
      url: "http://localhost", 
      data: queryString, 
      success: function(request) { bongo[i] = request } 
     }); 
    })(i); 
} 

bucles son el lugar # 1, donde las funciones en línea tocón personas. El bongo[i] = result no se llama hasta más tarde. El valor de i en ese momento es diferente (muy probablemente 11). Si desea "atrapar" o "capturar" el valor actual de i, debe crear un nuevo ámbito. La única forma de hacerlo en javascript es con otra función.

+0

Funciona como un encanto. Pero no obtuve lo que la final (i) hace, ¿podría alguien explicar eso? –

+0

el valor de exterior i pasa a la función anónima de autoimpresión de envoltura; la ubicación de este valor único es capturada por la devolución de llamada asíncrona. De esta forma, cada asincrónica obtiene su propio valor, determinado en el momento en que se invoca la función autoejecutable. ¡Ese es el punto de un cierre! ;) – Plastic

4

Probar:

var bongo = []; 
for (i=0; i<10; i++) { 
    $.get("http://localhost", function(result) { 
    bongo.push(result); 
    } 
} 

De esta manera cada resultado se consigue simplemente empujado sobre la matriz, la solución de la necesidad de que los índices de matriz sean correctas. Sin embargo, el pedido no está garantizado. Si ese es un requisito, necesitarás otro enfoque.

Existen varias formas de resolver este problema. Aquí hay uno: cree objetos para su devolución de llamada para guardar el estado. Aquí está un ejemplo:

function Callback(array, index, result) { 
    this.array = array; 
    this.index = index; 
    this.result = result; 
    var obj = this; 
    this.func = function() { 
    obj.array[obj.index] = obj.result; 
    }; 
} 

$(function() { 
    var arr = []; 
    for (var i=0; i<4; i++) { 
    var obj = new Callback(arr, i, "result" + i); 
    setTimeout(obj.func, (5-i) * 100); 
    } 
    setTimeout(function() { 
    console.log(arr); 
    }, 500); 
}); 

Así, en su caso:

function Callback(array, index) { 
    this.array = array; 
    this.index = index; 
    var obj = this; 
    this.callback = function(result) { 
    obj.array[obj.index] = result; 
    }; 
} 

var bongo = []; 
for (i=0; i<10; i++) { 
    var ob = new Callback(bongo, i); 
    $.get("http://localhost", ob.callback); 
} 

Básicamente lo anterior guarda todos los datos a un objeto y por lo tanto cada una devolución de llamada tiene acceso a la información correcta.

Además, tenga en cuenta que la mayoría de los navegadores limitan el número de solicitudes simultáneas de AJAX, por lo general a 2 por host.

+0

Pero de esta manera no puedo decidir exactamente en qué lugar de la matriz se envían los datos, que es lo que necesito. – Heilemann

+0

@Heilemann agregó una versión que guarda los índices en el orden correcto. – cletus