2011-05-20 15 views
30

Tengo un bucle for que encierra una llamada ajax y estoy tratando de determinar el mejor método para pasar el índice del bucle for a la función de devolución de llamada. Aquí está mi código:pasando el índice de forzado a la función de devolución de llamada ajax (JavaScript)

var arr = [2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010]; 

for (var i = 0; i < arr.length; i++) 
{ 
    $.ajaxSetup({ cache:false }) 
    $.getJSON("NatGeo.jsp", { ZipCode: arr[i], Radius: 
      document.getElementById("radius").value, sensor: false },  
      function(data) 
      { 
       DrawZip(data, arr[i]); 
     } 
); 
} 

En la actualidad, sólo el último valor de la matriz arr se pasa debido a la llamada AJAX asíncrona. ¿Cómo puedo pasar cada iteración de la matriz de arr a la función de devolución de llamada, además de ejecutar la llamada ajax sincrónicamente?

+2

aunque esto es un duplicado de alrededor [30 otras preguntas] (http://stackoverflow.com/questions/tagged/javascript+closures+loops), es un problema muy común al usar funciones dentro de los bucles, y espero que no te importe que modifique uno de los etiquetas para aumentar esa cuenta hasta 31 :) – Anurag

Respuesta

60

Se puede usar un Javascript cierre:

for (var i = 0; i < arr.length; i++) { 
    (function(i) { 
    // do your stuff here 
    })(i); 
} 

O usted podría utilizar $.each:

var arr = [2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010]; 

$.each(arr, function(index, value) { 
    $.ajaxSetup({ cache:false }); 
    $.getJSON("NatGeo.jsp", { ZipCode: value, Radius: 
    document.getElementById("radius").value, sensor: false },  
    function(data) { 
     DrawZip(data, value); 
    } 
); 
}); 
+0

¡Increíble, genial! ¡Gracias! – user717236

+0

No vale la pena que estas dos soluciones sean las mismas, y no hay nada mágico sobre '$ .each'. En ambos casos, se utilizó una función anónima para crear un cierre. – eradman

+0

Excelente respuesta. Gracias. –

5

no he leído todas las 30 preguntas @Anurag la lista, pero me encontré con la siguiente devolución de llamada sintaxis que parece funcionar:

(function(year) { 
    return (function(data) {DrawZip(data, year);}); 
})(arr[i]) 

Esto reemplaza al original function(data). Por cierto, los resultados están en orden aleatorio, debido a la respuesta asíncrona

+0

Esto también es bueno. ¡Gracias! – user717236

+0

Usted es bienvenido. :) – yitwail

+0

Has ahorrado mi tiempo. Gracias. – seenimurugan

3

Usted puede incluso omitir los paréntesis, para bucle como se ha mencionado por John Resig here creo que de esta manera es más fácil de leer

for (var i = 0; i < arr.length; i++) (function(i) { 

    // async processing 
    setTimeout(function(){ 
     console.log(i); 
    }, i * 200); 

})(i); 
Cuestiones relacionadas