2013-02-11 18 views
5

muszę dokonać sekwencyjnych asynchronicznych żądań AJAX przy ograniczonych strumieni. Jak na razie mogę zajmować tylko jeden strumień na serwerze sieciowym, więc mogę tylko wykonać jedno zapytanie ajaxowe w czasie.Jak zrobić sekwencyjnych asynchronicznych żądań AJAX z danej liczby strumieni

Mam następujących funkcji, która pomaga mi, kiedy wolno mi użyć tylko jeden strumień naraz.

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 
    } 
    } 

powiedzieć, jeśli mam trzy ajax funkcji pomocniczych

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 
} 

następujące połączenia zapewnia, że ​​żaden wniosek więcej niż 1 ajax jest wykonany z tego klienta

initiateChain(getGadgets, getBooks, getDeals); 

Teraz muszę poprawić initiateChain do obsługi dowolnej liczby strumieni. Powiedzmy, że mogę użyć 2 lub n liczby strumieni, chciałbym znać pomysły, aby to zrobić bez zmiany funkcji pomocnika ajax getGadgets, getDeals, getDeals.

Krótko mówiąc, mam zestaw funkcji, N, w tym przypadku getGadgets, getDeals i getDeals (| N | = 3), z których każdy potrzebuje połączenia z serwerem sieciowym. Obecnie mogę wykonać tylko jedno żądanie naraz, dlatego funkcja initiate wywołuje kolejno trzy metody. Gdybym miał dostęp do połączeń M, chciałbym wykonać | N | działa równolegle (maksymalnie do M).

+1

Na czym dokładnie polega twoje pytanie? – jfriend00

+0

Jak wspomniałem Mam zestaw funkcji, N, w tym przypadku getGadgets, getDeals i getDeals (| N | = 3), że każdy potrzebuje połączenia z serwerem WWW. Obecnie mogę wykonać tylko jedno żądanie naraz, dlatego funkcja initiate wywołuje kolejno trzy metody. Gdybym miał dostęp do połączeń M, chciałbym wykonać | N | działa równolegle (maksymalnie do M). – harsha

Odpowiedz

14

Jeśli używasz jQuery można użyć jej do metody .queue umieść w kolejce swoje wywołania ajaxowe, a następnie wykonaj je kolejno. Aby uruchomić wiele sekwencji, możesz zawinąć początkową kolejkę w pętli.

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

Dziękuję. Działa zgodnie z oczekiwaniami. – harsha

+0

jeśli to zadziałało, możesz oznaczyć odpowiedź jako zwycięską odpowiedź. dzięki –

+0

To jest mądre! Wielkie dzięki. – Kevindra

1

Dopóki twoje wywołania zwrotne są synchroniczne to powinno działać dla ciebie, jeśli nie można umieścić na dobrej drodze

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

Dzięki @James, mam pojęcia od czego skrócone. Jako takie połączenia są asynchroniczne żądania ajax. Pomysł polega więc na stworzeniu liczby M połączeń asynchronicznych z góry. Wtedy będą kontynuować te wszystkie, kiedy i kiedy każdy jest kompletny.

Zrobiłem eksperyment z nodejs i następuje initiateChain działa zgodnie z przeznaczeniem

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]); 

W moim doświadczeniu mam następujące wyniki

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 
Powiązane problemy