2010-07-13 21 views
10

Ho riscontrato un problema durante l'utilizzo delle funzioni jquery .each() e .ajax() insieme. Sto usando .each() per effettuare il ciclo di 5 elementi e sto eseguendo la chiamata .ajax() per ognuno. Il mio problema è che voglio solo che il ciclo continui quando una risposta è stata ricevuta da ogni richiesta Ajax. Attualmente, tutti i 5 elementi sono in loop, vengono eseguite 5 richieste Ajax, quindi vengono restituite 5 risposte.Jquery chiamata ajax all'interno di ciascun loop

Il suo è un semplice esempio:

$(".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. 

     } 
    }); 

}); 

Cin cin.

risposta

10

Si potrebbe utilizzare l'opzione async per questo per rendere ogni richiesta sincrono (= esecuzione dello script arresto finché ogni richiesta è completata):

asincrona asincrono Per default, tutte le richieste sono inviate (cioè questo è impostato su true per impostazione predefinita). Se hai bisogno di richieste sincrone, imposta questa opzione su false. Richieste tra domini e dataType: le richieste "jsonp" non supportano l'operazione sincrona. Si noti che le richieste sincrone possono bloccare temporaneamente il browser, disabilitando tutte le azioni mentre la richiesta è attiva.

ma, come i documenti dicono già, questo è altamente sconsigliato, in quanto potrebbe bloccare il browser se una richiesta si blocca o timeout.

Sarebbe meglio cambiare l'architettura del codice in un modo che possa funzionare con le funzioni di callback classiche, se possibile.

+4

Applausi per l'aiuto, ho seguito il tuo suggerimento e modificato la struttura del mio codice, ho rimosso il ciclo e usato la ricorsione. Funziona bene ora. – DazzledKid

2

Pekka ha la risposta corretta. Hai solo bisogno di modificare il tuo script come di seguito.

$(".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

Ho provato questo, posso capire perché è altamente scoraggiato. L'impostazione apparentemente falsa causa il blocco del mio browser fino a quando non sono state ricevute tutte le risposte e il ciclo è terminato. – DazzledKid

+0

Non sono sicuro di cosa si aspettasse che si verifichi. Se vuoi che lo script si interrompa e aspetti la risposta, allora farà esattamente quella pausa e attenderà. Forse dovresti spiegare che cosa esattamente stai cercando di ottenere perché potrebbe esserci un modo migliore. C'è probabilmente un modo migliore per raggiungere i risultati finali che desideri con un algoritmo diverso. – YonahW

0

sono felice di dire che c'è un modo ... ma è un po 'brutto.

Se si è sicuri che la richiesta deve restituire qualcosa, è possibile rimuovere 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

Perché non limitarsi ad uscire da ogni loop quando la prima richiesta di ajax restituisce successo? – markus

Problemi correlati