#javascript #jquery #ajax #jquery-deferred
#javascript #jquery #ajax #jquery-отложенный
Вопрос:
Мне нужно запустить несколько ajax-запросов на сервере, а затем выполнить обратный вызов, когда они будут завершены. Обычно это было бы легко сделать с помощью jQuery deferred.done()
. Однако, чтобы избежать перегрузки сервера, я ставлю запросы в очередь и запускаю по одному каждые X миллисекунд.
например
var promisesList = [];
var addToQueue = function(workflow) {
workflowQueue.push(workflow);
}
var startWorkflow = function(workflow) {
return $.ajax($endointURL, {
type: "POST",
data: {
action: workflow.id
},
success: function() {
},
error: function(jqXHR, textStatus, errorThrown) {
}
});
};
var startWorkflows = function() {
var promisesList = [];
if (workflowQueue.length > 0) {
var workflow = workflowQueue.shift();
promisesList.push(startWorkflow(workflow));
setTimeout(startWorkflows, delay);
}
};
startWorkflows();
$.when(promisesList).done(function(){
//do stuff
});
Проблема с этим заключается в том, что promisesList
массив изначально пуст, поэтому done()
обратный вызов запускается немедленно, а затем setTimeout()
запросы ajax начинают отправляться с помощью. Существует ли простой способ изначально создавать запросы ajax и как бы «приостанавливать» их, а затем запускать с помощью setTimeout()
.
Я нашел различные реализации регулирования / очереди для последовательного запуска запросов ajax, но я рад, что они запускаются параллельно, просто с задержкой на них.
Комментарии:
1.
setTimeout
с произвольной задержкой не вариант?2. Я использую
setTimout()
, проблема заключается в обработкеdeferred
объектов.3. Я предполагаю, что вам нужно обрабатывать часть $.when для каждого запроса… или что вы ждете, пока все не будут отправлены, а затем делаете, когда …
Ответ №1:
Первое, на что вы натыкаетесь, это то, что when()
это не работает таким образом с массивами. Он принимает произвольный список обещаний, поэтому вы можете обойти это, применив массив с помощью:
$.when.apply(null, promiseList).done(function(){
// Do something
// use the `arguments` magic property to get an ordered list of results
});
Во-вторых, метод регулирования может быть выполнен с помощью параметра $.ajax {delay:timeInSeconds}, но я предложил решение, которое устанавливает новую отсрочку, которая немедленно возвращается (для сохранения порядка), но разрешается по истечении времени ожидания.
Смотрите http://jsfiddle.net/9Acb2/1 для интерактивного примера
Комментарии:
1. (a) Я был уверен, что это
$.when()
сработает именно так! Проверено, и вы правы, он не принимает массивы. Странно, кажется очевидной вещью для этого. (b) я не вижуdelay
параметра в документах jQ для запросов ajax? (c) Ваша скрипка идеальна, я не думал о создании$.Deferreds()
такого вручную. Большое спасибо!