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