2010-07-13 65 views
10

Tengo un problema al usar las funciones jquery .each() y .ajax() juntas. Estoy usando .each() para recorrer 5 elementos y estoy realizando la llamada .ajax() para cada uno. Mi problema es que solo quiero que el ciclo continúe cuando se recibe una respuesta de cada solicitud de Ajax. Actualmente, los 5 elementos están siendo enlazados, se hicieron 5 solicitudes ajax y luego se devolvieron 5 respuestas.Llamada Jquery ajax dentro de cada bucle

El suyo es un ejemplo sencillo:

$(".element").each(function() { 
    var id= $(this).find(('txtId').val(); 
    $.ajax({ 
     type: "POST", 
     url: "/Handlers/Handler.ashx", 
     data: "ID=" + id, 
     success: function(xml){ 

     // I would like the each() loop to pause until this is hit, 
     // and some additional logic can be performed. 

     } 
    }); 

}); 

Saludos.

Respuesta

10

usted podría utilizar la opción async para que esto se haga cada solicitud síncrona (= ejecución del script detuvo hasta que cada petición es terminado):

asíncrono asíncrono Por defecto, todas las peticiones se envían (es decir, este se establece en verdadero por defecto). Si necesita solicitudes sincrónicas, establezca esta opción en falso. Solicitudes entre dominios y tipo de datos: las solicitudes "jsonp" no son compatibles con la operación síncrona. Tenga en cuenta que las solicitudes sincrónicas pueden bloquear temporalmente el navegador, deshabilitando cualquier acción mientras la solicitud está activa.

pero, como dicen los documentos, esto es muy desaconsejable, ya que podría congelar el navegador si una solicitud se bloquea o se agota el tiempo de espera.

Sería mejor cambiar la arquitectura de su código de manera que pueda funcionar con las funciones de devolución de llamada clásica si es posible.

+4

Saludos por la ayuda, he ido con su sugerencia y he cambiado la estructura de mi código, he eliminado el ciclo y uso recursividad en su lugar. Funciona bien ahora – DazzledKid

2

Pekka tiene la respuesta correcta. Solo necesita editar su script de la siguiente manera.

$(".element").each(function() { 
    var id= $(this).find(('txtId').val(); 
    $.ajax({ 
     type: "POST", 
     async: false, 
     url: "/Handlers/Handler.ashx", 
     data: "ID=" + id, 
     success: function(xml){ 

     } 
    }); 

}); 
+0

He intentado esto, puedo ver por qué está muy desaconsejado. Al parecer, establecer esto en falso hace que mi navegador se congele hasta que se hayan recibido todas las respuestas y el ciclo haya finalizado. – DazzledKid

+0

No estoy seguro de lo que esperaba. Si desea que el script se detenga y espere la respuesta, hará exactamente esa pausa y esperará. Tal vez deberías explicar qué es exactamente lo que buscas lograr, ya que puede haber una manera mejor. Probablemente haya una mejor manera de lograr los resultados finales que desee con un algoritmo diferente. – YonahW

0

estoy feliz de decir que hay una manera ... pero es un poco desagradable.

Si está seguro de que la solicitud tiene que devolver algo, puede eliminar la parte "tryIteration".

$(document).ready(function() { 

     loop(".buttonsPromotion", 0); 

}); 

function loop(elements, tryIteration) { 
//HOW MANY TRIES UNTIL WE STOP CHECKING 
if(tryIteration<7){ 

    $(elements).each(function() {    
     var actuel = $(this); 
     $.ajax({ 
      url: "write your link here", 
      data: {}, 
      dataType: 'json', 
      async: true, 
      success: function(data){ 
       //HERE WE KNOW THE AJAX REQUEST WENT OK 
       actuel.addClass('AjaxOK');  
      }, 
      error:function(thrownError){ 
       console.log(thrownError); 
       //WE MAKE ANOTHER EACH ON ALL ELEMENT THAT WENT BAD 
       var elemToRetry = actuel.not('AjaxOK'); 
       loop(elemToRetry, ++tryIteration); 
      } 
     }); 

    }); 
} 
} 
+0

¿Por qué no acaba de salir de cada bucle cuando la primera solicitud de ajax devuelve éxito? – markus

Cuestiones relacionadas