2013-02-11 5 views
5

Мне нужно сделать последовательные асинхронные запросы ajax с ограниченными потоками. На данный момент мне разрешено занимать только один поток на веб-сервере, поэтому я могу выполнить только один запрос ajax.Как выполнить последовательные асинхронные запросы ajax с заданным количеством потоков

У меня есть функция, которая помогает мне, когда мне разрешено использовать только один поток за раз.

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

Скажет, если у меня есть три АЯКС вспомогательных функций

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 
} 

следующих вызова гарантирует, что запрос не более 1 Аякса не сделан от этого клиента

initiateChain(getGadgets, getBooks, getDeals); 

Теперь мне нужно усилить initiateChain для поддержки произвольного количества потоков. Скажем, мне разрешено использовать 2 или n количество потоков, которые я хотел бы знать, чтобы сделать это, не меняя вспомогательные функции ajax getGadgets, getDeals, getDeals.

Короче говоря, у меня есть набор функций, N, в этом случае getGadgets, getDeals и getDeals (| N | = 3), для каждого из которых требуется подключение к веб-серверу. В настоящее время я могу выполнять только один запрос за раз, поэтому функция initiateChain вызывает три метода в последовательности. Если бы у меня был доступ к M-соединениям, я хотел бы выполнить | N | функции параллельно (до максимума M).

+1

Что именно ваш вопрос? – jfriend00

+0

Как я уже говорил У меня есть набор функций, N, в этом случае getGadgets, getDeals и getDeals (| N | = 3), для каждого из которых требуется подключение к веб-серверу. В настоящее время я могу выполнять только один запрос за раз, поэтому функция initiateChain вызывает три метода в последовательности. Если бы у меня был доступ к M-соединениям, я хотел бы выполнить | N | функции параллельно (до максимума M). – harsha

ответ

14

Если вы используете JQuery, то вы можете использовать его метод .queue к поставите в очередь ваши вызовы ajax, а затем выполните их последовательно. Чтобы запустить несколько последовательностей, вы можете перенести начальный dequeue в цикле.

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

Спасибо. Он работает по своему желанию. – harsha

+0

Если это сработало, можете ли вы пометить ответ как выигрышный ответ. спасибо –

+0

Это умный! Большое спасибо. – Kevindra

1

Пока ваши обратные вызовы все синхронные это должно работать для вас, если не поставить вас на правильном пути

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

Благодаря @James, я получил ключ от того, что вы редактировали для длины. Таким образом, вызовы представляют собой асинхронные запросы async. Таким образом, идея заключается в создании M-номера асинхронных вызовов upfront. Тогда они будут продолжать эти многие, когда и когда каждый будет завершен.

я сделал эксперимент с nodejs и следующие initiateChain работы по назначению

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

В моем опыте я получил следующие результаты

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 
Смежные вопросы