А помните все те велосипеды, которые приходилось писать для обработки множества асинхронных вызовов? Скажем, у нас есть 10 функций или ajax-запросов. Нужно вызвать их все, подождать пока они отработают, а потом выполнить какой-то общий код. Знакомо, не правда ли? И вот, я случайно обнаружил, что в jQuery подобные вещи уже давно реализованы и их можно использовать. Называется всё это jQuery.Deferred.
Итак, попробуем написать тестовое приложение. Оно запускает 10 таймеров с различным временем. И когда все таймеры сработают, приложение должно вывести какое-нибудь сообщение.
var doAction = function (i) {
var d = new $.Deferred();
setTimeout(function () {
console.log(i + ' done.');
d.resolve();
}, Math.random() * 9000 + 1000);
return d.promise();
};
$(function () {
var actions = [];
for (var i = 0; i < 10; ++i) {
actions.push(doAction(i));
}
$.when.apply(this, actions).then(function () {
console.log('Everything is ok.');
});
});
У объекта Deferred
довольно много всяческих методов, но нам интересно несколько. Метод promise
возвращает специальный объект, с помощью которого можно отслеживать состояние выполняемой задачи, методы resolve
и reject
завершают задачу успешно и не успешно соответственно.
Получив набор объектов promise, мы можем их комбинировать. В нашем случае с помощью $.when
создаем новый deferred-объект, который является объединением всех остальных. Ну и с помощью then
вешаем общую функцию, которая сработает самой последней.
Ну и напоследок, $.ajax тоже является deferred объектом, поэтому можно написать:
$.when($.ajax(a), $.ajax(b)).then(function () {});
И получить обработчик, который выполнится после завершения всех запросов. Хотя что я вам тут рассказываю, вы ведь всё это знаете и без меня.
Хочется что-то добавить или сказать? Я всегда рад обсудить. Пишите на me@dikmax.name.