2013-08-25 14 views
8

Sto provando a caricare un gruppo di dati da un'API asincrona e quando tutti i dati sono caricati voglio attivare un evento che tutti i dati siano caricati. Il problema che sto avendo è che l'API che sto usando limita il numero di oggetti risposta a cinque. E potenzialmente avrei bisogno di recuperare 30-40 oggetti di risposta.Come eseguire il looping delle richieste Ajax all'interno di una frase JQuery When - Then?

Quindi, quello che voglio fare è creare un'istruzione when-then che giri attraverso gli elementi di dati e faccia richiesta per ogni cinque elementi, quindi quando tutti gli elementi sono caricati voglio sparare un evento caricato. Il problema che sto avendo è che l'istruzione when-then sta completando prima del successo della richiesta Ajax.

sul codice che ho provato.

function loadsLotsOfStats(stats, dataType, eventName, dataName, callback) { 
    var groupedStats = []; 
    while (stats.length > 0) { 
     groupedStats.push(stats.splice(0, 5).join('/')); 
    } 
    j$.when(
     groupedStats.forEach(function (d) { 
      loadJSONToData(model.apiUrl.replace("{IDS}", d), "json", "", dataName, function (d) { /*console.log(d);*/ }, true) 
     }) 
    ).then(function() { 
     j$(eventSource).trigger('dataLoaded', eventName); 
    }); 

La funzione loadJSONToData è fondamentalmente solo una funzione wrapper per un Async $ .ajax.

quindi sì, l'evento viene attivato prima che i dati vengano effettivamente caricati. Anche per qualche ragione se provo a mettere il ciclo giusto nel momento in cui (lo dichiaro tramite un errore di sintassi?

Qualcuno ha qualche consiglio su come potrei fare una serie di richieste Ajax e attendere fino a quando non sono tutti stati precedentemente dell'attivazione di un evento? O una via per risolvere quello che ho attualmente?

Grazie in anticipo per l'aiuto.

+0

Si può anche usare 'if (condition.length <10) {// code per eseguire}'. –

+0

Possibile duplicato di [Cercando di effettuare 2 chiamate Ajax tramite JQuery e quindi anteporre i dati (presi da Freecodecamp Twitch Project)] (http://stackoverflow.com/questions/42425885/trying-to-make-2-ajax- chiamate-via-jquery-e-poi-anteporre-i-dati-presi da) –

risposta

16

e 'possibile fare ciò che si Chiedete SEMPRE, il server che state inviando le vostre richieste a probabilmente ha ar eason per il limite che impongono. Come qualcuno che lavora nello sviluppo web e ha visto in prima persona quanto possano essere fastidiosi DDOS, scraping e altri abusi delle API, suggerirei di conformarsi al loro limite.

Detto questo, ecco come puoi farlo.

$ .ajax restituisce effettivamente un oggetto posticipato, quindi è possibile utilizzarlo a proprio vantaggio. Inoltre $ .quando può accettare qualsiasi numero di oggetti differiti. Combinare questi due fatti può risolvere il tuo problema.

var deferreds = []; 
$.each(groupedStats, function(index, stat){ 
    deferreds.push(
     // No success handler - don't want to trigger the deferred object 
     $.ajax({ 
      url: '/some/url', 
      data: {stat: stat}, 
      type: 'POST' 
     }) 
    ); 
}); 
// Can't pass a literal array, so use apply. 
$.when.apply($, deferreds).then(function(){ 
    // Do your success stuff 
}).fail(function(){ 
    // Probably want to catch failure 
}).always(function(){ 
    // Or use always if you want to do the same thing 
    // whether the call succeeds or fails 
}); 

Si noti che questa non è una condizione di competizione. Sebbene $ .ajax sia asincrono, $ .each non lo è, quindi l'elenco dei differiti sarà la lista totale prima di arrivare a $ .when e $ .then/$. Fail/$. Verrà sempre attivato solo quando tutti saranno completi .

EDIT: Ho dimenticato di aggiungere lo splitting per 5 s, ma questo illustra l'idea generale. Probabilmente puoi capire da qui come applicarlo al tuo problema. Per inciso, si potrebbe semplicemente usare array.splice (0,5) per ottenere i prossimi 5 risultati dalla matrice. .splice è sicuro da usare; se il numero totale di elementi è inferiore a 5, prenderà solo tutti gli elementi rimanenti.

+2

Pollice su, questo funziona esattamente come ne ho bisogno. Ottima risposta e buona spiegazione. Grazie per il tempo. E sì, guarderò in un modo diverso di accedere ai dati di cui ho bisogno, dal momento che il tuo limite è lì per un motivo. – recneps

+0

grande spiegazione! Funziona come un fascino. – Mike

+0

Mi dispiace se mi manca, ma come si cattura e valutato la risposta – atwellpub

Problemi correlati