2013-02-11 3 views
5

Ich muss sequentielle asynchrone Ajax-Anfragen mit begrenzten Streams machen. Ab jetzt darf ich nur noch einen Stream auf dem Webserver belegen, so dass ich nur eine Ajax-Anfrage machen kann.So führen Sie sequenzielle asynchrone Ajax-Anfragen mit einer bestimmten Anzahl von Streams durch

Ich habe folgende Funktion, die mir hilft, wenn ich nur einen Strom zu einer Zeit verwenden darf.

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

sagen, wenn ich drei Ajax-Helferfunktionen haben

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 
} 

folgende Aufruf stellt sicher, dass nicht mehr als 1 Ajax-Anforderung von diesem Client gemacht wird

initiateChain(getGadgets, getBooks, getDeals); 

Jetzt muss ich initiateChain verbessern um eine beliebige Anzahl von Streams zu unterstützen. Sagen wir, ich darf 2 oder n Streams verwenden, von denen ich gerne wissen möchte, dass sie dies tun, ohne die ajax-Hilfsfunktionen getGadgets, getDeals und getDeals zu ändern.

Kurz gesagt, ich habe eine Reihe von Funktionen, N, in diesem Fall getGadgets, getDeals und getDeals (| N | = 3), die jeweils eine Verbindung zum Webserver benötigen. Momentan kann ich nur eine Anfrage gleichzeitig ausführen, also ruft die initiateChain-Funktion die drei Methoden nacheinander auf. Wenn ich Zugriff auf M-Verbindungen hätte, würde ich gerne | N | ausführen funktioniert parallel (bis zu einem Maximum von M).

+1

Was genau ist Ihre Frage? – jfriend00

+0

Wie ich erwähnt habe, habe ich eine Reihe von Funktionen, N, in diesem Fall getGadgets, getDeals und getDeals (| N | = 3), die jeweils eine Verbindung zum Webserver benötigen. Momentan kann ich nur eine Anfrage gleichzeitig ausführen, also ruft die initiateChain-Funktion die drei Methoden nacheinander auf. Wenn ich Zugriff auf M-Verbindungen hätte, würde ich gerne | N | ausführen funktioniert parallel (bis zu einem Maximum von M). – harsha

Antwort

14

Wenn Sie jQuery verwenden, dann können Sie seine .queue Methode verwenden, Stellen Sie Ihre Ajax-Anrufe in eine Warteschlange und führen Sie sie dann nacheinander aus. Um mehrere Sequenzen auszuführen, können Sie die ursprüngliche Warteschlange in eine Schleife umbrechen.

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

Danke. Es funktioniert wie gewünscht. – harsha

+0

Wenn es funktioniert, können Sie die Antwort als die beste Antwort markieren. danke –

+0

Das ist schlau! Danke vielmals. – Kevindra

1

Solange Ihre Rückrufe alle synchron sind dies sollte für Sie arbeiten, wenn Sie nicht auf dem richtigen Weg

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

Dank @James habe ich Ahnung von dem, was Sie für Länge bearbeitet. Die Aufrufe sind asynchrone Ajax-Anfragen. Also die Idee ist M Anzahl der asynchronen Anrufe Upfront erstellen. Dann werden sie so viele fortsetzen, wie und wenn jeder abgeschlossen ist.

Ich habe Experiment mit NodeJS und nach initiateChain als

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

bekam folgende In meinem Experiment bestimmt Werke I Ergebnisse

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 
Verwandte Themen