Deferred объект в jQuery
В jQuery 1.5 появился новый объект deferred, призванный облегчить работу с асинхроными действиями.
Давайте рассмотрим пример работы с ajax запросами, где нам надо сделать 2 последовательных асинхронных запроса.
// Дожидаемся загрузки документа
$(document).ready(function() {
// Выполняем первый запрос
$.get("get-user-id.php", {dataType: "json"})
.done(function(data) {
// Если первый запрос был успешно выполнен, выполняем второй запрос
$.get("get-user-name-by-id.php", {userId: data.userId}, function() {}, "json")
.done(function(data) {
// Если второй запрос был успешно выполнен, выводим приветствие
console.log("Здравствуйте " + data.userName);
})
.fail(function() {
// Если возникли проблемы со вторым запросом, выводим ошибку
console.log("Ошибка при получении имени пользователя");
});
})
.fail(function() {
// Если возникли проблемы с первым запросом, выводим ошибку
console.log("Ошибка при получении id пользователя");
});
});
Каждый последующий запрос находится внутри callback функции предыдущего, поэтому вложенность функций растет.
К томуже для каждого запроса нам надо писать свой обработчик ошибок, что не всегда то и нужно.
Как вы наверное уже поняли, решить эти проблемы и призван объект deferred.
Давайте перепишем этот код с использованием jQuery объекта deferred.
// Дожидаемся загрузки документа
$.when($(document).ready())
// Выполняем первый запрос
.then($.get("get-user-id.php", {dataType: "json"}))
// Если первый запрос был успешно выполнен, выполняем второй запрос
.then(function(data) {
return $.get("get-user-name-by-id.php", {userId: data.userId}, function() {}, "json");
})
// Если второй запрос был успешно выполнен
.done(function(data) {
console.log("Здравствуйте " + data.userName);
})
// Если возникли проблемы, хоть в одном запросе, выводим ошибку
.fail(function() {
console.log("Ошибка при получении id или имени пользователя");
});
Таким образом мы работаем с асинхронным кодом, так же как с синхронным. К тому же мы использовали общий обработчик ошибок.
Давайте рассмотрим еще один пример.
Нам надо отобразить сообщение когда пользователь нажмет на обоих кнопках в произвольном порядке. С deferred объектом это проще простого.
<button id="button1">Button 1</button>
<button id="button2">Button 2</button>
<script type="text/javascript">
// Создаем Deferred объект для каждой кпопки
var deferred1 = $.Deferred(),
deferred2 = $.Deferred();
// Переводим соответствуюший deferred объект в статус resolve при клике на кнопке
$("#button1").click(deferred1.resolve);
$("#button2").click(deferred2.resolve);
// Когда оба deferred объекта будут в статусе resolve, выводим сообщение
$.when(deferred1, deferred2).done(function() {
console.log("Ready!");
});
</script>
Автор: http://www.nika.org.ua
Дата: 16.10.13
