2013-02-11 7 views
5

È necessario effettuare richieste ajax asincrone sequenziali con flussi limitati. A partire da ora ho il permesso di occupare un solo stream sul web server in modo da poter fare solo una richiesta ajax alla volta.Come eseguire richieste Ajax asincrone sequenziali con un determinato numero di flussi

Ho la seguente funzione che mi aiuta quando sono autorizzato a utilizzare un solo flusso alla volta.

function initiateChain() { 
    var i = 0; 
    var tasks = arguments; 
    var callback = function() { 
     i += 1; 
     if (i != tasks.length) { 
     tasks[i](callback); //block should call callback when done otherwise loop stops 
     } 
    } 
    if (tasks.length != 0) { 
     tasks[0](callback); //initiate first one 
    } 
    } 

dire se ho tre funzioni di aiuto ajax

function getGadgets(callback) { 
     //ajax call 
     callback(); // I call this in complete callback of $.ajax 
} 

function getBooks(callback) { 
     //ajax call 
     callback(); // I call this in complete callback of $.ajax 
} 

function getDeals(callback) { 
     //ajax call 
     callback(); // I call this in complete callback of $.ajax 
} 

seguenti chiamata assicura che nessuna richiesta più di 1 ajax è fatto da questo client

initiateChain(getGadgets, getBooks, getDeals); 

ora ho bisogno di migliorare initiateChain supportare un numero arbitrario di flussi. Supponiamo che io possa utilizzare il numero 2 o n di stream che mi piacerebbe conoscere le idee per farlo senza cambiare le funzioni di helper di ajax getGadgets, getDeals, getDeals.

In breve, ho un set di funzioni, N, in questo caso getGadgets, getDeals e getDeals (| N | = 3) che richiedono ciascuna una connessione al server web. Attualmente, posso eseguire solo una richiesta alla volta, quindi la funzione initiateChain chiama i tre metodi in sequenza. Se avessi accesso alle connessioni M, vorrei eseguire | N | funziona in parallelo (fino a un massimo di M).

+1

Qual è esattamente la tua domanda? – jfriend00

+0

Come ho detto ho un set di funzioni, N, in questo caso getGadgets, getDeals e getDeals (| N | = 3) che richiedono ciascuna una connessione al server web. Attualmente, posso eseguire solo una richiesta alla volta, quindi la funzione initiateChain chiama i tre metodi in sequenza. Se avessi accesso alle connessioni M, vorrei eseguire | N | funziona in parallelo (fino a un massimo di M). – harsha

risposta

14

Se stai usando jQuery è possibile utilizzare il metodo di .queue accodare le chiamate ajax e quindi eseguirle in sequenza. Per eseguire più sequenze, è possibile racchiudere il riepilogo iniziale in un ciclo.

function add_api_call_to_queue(qname, api_url) { 
    $(document).queue(qname, function() { 
     $.ajax({ 
      type  : 'GET', 
      async : true, 
      url  : api_url, 
      dataType : 'json', 
      success : function(data, textStatus, jqXHR) { 
       // activate the next ajax call when this one finishes 
       $(document).dequeue(qname); 
      } 
     }); 
    }); 
} 

$(document).ready(function() { 

    var queue_name  = 'a_queue'; 
    var concurrent_calls = 2; 

    // add first AJAX call to queue 
    add_api_call_to_queue(queue_name, '/example/api/books'); 

    // add second AJAX call to queue 
    add_api_call_to_queue(queue_name, '/example/api/dvds'); 

    // add third AJAX call to queue 
    add_api_call_to_queue(queue_name, '/example/api/shoes'); 

    // start the AJAX queue 
    for (i=0;i<concurrent_calls;i++) { 
     $(document).dequeue(queue_name); 
    } 

}) 
+0

Grazie. Funziona come desiderato – harsha

+0

se ha funzionato, puoi contrassegnare la risposta come la risposta vincente. grazie –

+0

Questo è intelligente! Molte grazie. – Kevindra

1

Finché i tuoi callback sono tutti sincroni questo dovrebbe funzionare per voi, se non si mette sulla strada giusta

var initiateChain = function() { 

    var args = arguments, 
     index = 0, 
     length = args.length, 
     process = function (index) { 

      if (index < length) { 
       $.ajax({ 
        url: '/example.php', 
        complete: function() { 
         // Callbacks get run here 
         args[ index ]; 
         process(++index); 
        } 

       }); 
      } 


     }; 

    if (length) { 
     process(0); 
    } 

}; 

initiateChain(getGadgets, getDeals, getDeals); 
0

Grazie @James, ho avuto indizio da quello che è stato modificato per la lunghezza. Di conseguenza, le chiamate sono richieste ajax asincrone. Quindi l'idea è di creare il numero M di chiamate asincrone in anticipo. Quindi continueranno quelli molti come e quando ognuno è completo.

ho fatto sperimentare nodejs e seguendo initiateChain funziona come previsto

var calls = []; 

function initiateChain() { 
    var i = 0; 
    var maxSteams = 2; 
    var tasks = arguments; 
    var callback = function() { 
     i += 1; 
     if (i < tasks.length) { 
     tasks[i](callback); //block should call callback when done otherwise loop stops 
     } 
    } 
    if (tasks.length) { 
     i = ((tasks.length > maxSteams) ? maxSteams : tasks.length) - 1; 
     for (var j = 0; j < maxSteams; j+=1) { 
     if (j < tasks.length) { 
      tasks[j](callback); //initiate first set 
     } else { 
      break; 
     } 
     } 
    } 
} 

//test methods 
for(var k = 0; k < 8; k+=1) { 
    calls[k] = (function (message, index) { 
    return function (callback) { 
     var ts = new Date().getTime(); 
     console.log(message + " started - " + ts); 
     setTimeout(function() { 
     ts = new Date().getTime(); 
     console.log(message + " completed - " + ts); 
     callback(); 
     }, index * 1000); 
    }; 
    })("call" + (k+1), (k+1)) 
} 

initiateChain(calls[0], calls[1], calls[2], calls[3], 
    calls[4], calls[5], calls[6], calls[7]); 

Nel mio esperimento ho ottenuto i seguenti risultati

call1 started - 1360580377905 
call2 started - 1360580377926 

call1 completed - 1360580378937 
call3 started - 1360580378937 

call2 completed - 1360580379937 
call4 started - 1360580379937 

call3 completed - 1360580381945 
call5 started - 1360580381945 

call4 completed - 1360580383946 
call6 started - 1360580383946 

call5 completed - 1360580386959 
call7 started - 1360580386959 

call6 completed - 1360580389950 
call8 started - 1360580389950 

call7 completed - 1360580393972 

call8 completed - 1360580397959 
Problemi correlati