В новой версии jQuery 1.5 было внесено много изменений, однако, основные изменения коснулись внедрения объекта Deferred() в каждый метод AJAX, а так же возможность создавать объект Deferred() почти для любых функций.

Метод Deferred() позволяет создавать очередность методов, которые выполняются в зависимости от готовности определенных функций, причем как пользовательских, так и встроенных в jQuery.

Объект Deferred() может быть использован как средство для отслеживания завершения других jQuery методов и для создания отсроченных действий, что окажется полезным для выполнения определенных действий на странице в зависимости от успешного выполнения, например, AJAX запроса или методов анимации.

eferred() поддерживает множественные обработчики для AJAX событий, теперь Вы можете привязывать обработчик, например success или complete, столько, сколько понадобится. Забегая вперед скажу, что примеры использования объекта Deffered() с множественными обработчиками указаны в 4-ом примере.

К объекту Deferred() команда разработчиков jQuery добавила множество сопутствующих ему методов, с помощью которых можно определять логику поведения объекта, его отмену и отслеживание, а так же передачу дополнительных объектов функциям объекта Deferred() как параметры.

Можно сказать что данный объект, по словам разработчиков jQuery, призван служить для повышения свободы действий разработчику для работы с функциями обратного вызова, которые в данном объекте не зависят от выполнения основных обработчиков методов jQuery.

В целом объект разработан на основе проекта Promises.

Возможности объекта Deferred

Объект Deferred() может быть использован в следующих случаях:

  • для создания отсроченных jQuery методов;
  • для создания очереди методов jQuery;
  • для передачи параметров в качестве аргументов функции обратного вызова метода done();
  • для отслеживания готовности jQuery методов;
  • для регулирования возможного поведения дальнейшей логики JS скрипта методами then() и fail().

При этом следует помнить:

  • так как объект Deferred() используется внутри каждого AJAX метода, допустимо вызывать сразу несколько обработчиков AJAX событий (см. пример 8);
  • при инициализации указывать оператор new необязательно;
  • объект Deferred() может принимать состояние resolve или reject один раз;
  • сопутствующие меотды, указанные ниже, могут быть использованы напрямую с объектом Deferred() либо, если объект передан в переменную, то вызывая каждый метод для данной переменной.

Все возможности Deferred() можно реализовать, используя добавленные вместе с ним, вспомогательные методы.

Вспомогательные методы объекта

  • deferred.done() — метод, выполняемый при успешном завершении метода, отслеживаемого методом resolve();
  • deferred.fail() — метод, выполняющийся при неуспешном завершении метода, отслеживаемого методомresolve();
  • deferred.isRejected() — возвращает true, если внутри объекта были вызваны методы reject() или rejectWith(), используется внутри метода fail();
  • deferred.isResolved() — возвращает true, если объект находится в состоянии resolve и означает, что внутри объекта были вызваны методы resolve() или resolveWith(), используется внутри метода done();
  • deferred.rejectWith() то же что и reject(), но передаёт в метод fail() параметр доступный через this;
  • deferred.resolve() — запускает отслеживание выполнения метода jQuery;
  • deferred.reject() — отклоняет отслеживание выполнения метода jQuery (7 пример);
  • deferred.resolveWith() — то же что и resolve(), но передаёт в метод done() параметр доступный через this (см.8-9 пример);
  • deferred.then() — метод создающий цепочку последовательных функций, далее используется во многих примерах этой статьи.

Сферы применения объекта

Объект Deferred() может применяться в методах анимации (например, для методов animatefadeOutfadeInshowи т.д.), во всех AJAX методах ($.get()$.post()$.ajax()$.getJSON()), при этом для методов AJAX создавать его явно нет надобности.

Deferred()предоставляет большие возможности при его использовании совмести с методом when, так же введённым в jQuery 1.5, например, теперь вы можете привязывать выполнение определенной функции к успешному выполнению нескольких ajax запросов или завершению процесса анимации, либо одновременно — и к успешному выполнению нескольких ajax запросов, и к завершению процесса анимации.

Примеры использования

Примеры инициализация

Как инициализировать объект Deferred()? Очень просто, как я указал ранее, вы можете передать объект в переменную и работать далее с переменной:

В следующем примере мы инициируем объект, после создаём метод dfd.resolve, как функцию обратного вызова, отслеживающую момент завершения анимации, созданной методом fadeIn. Конечно, вы можете спросить, зачем усложнять себе жизнь и создавать функцию обратного вызова таким непростым образом, когда можно указать в методеfadeIn обычную функцию обратного вызова? Если мы воспользуемся простой функцией обратного вызова, то мы не сможем создать множественные обработчики (пример 2).

Пример 1

Пример инициализации объекта Deferred() с множественными обработчиками.

Пример 2

Примеры объекта Deferred() в AJAX

Пример реализации объекта Deferred(), когда действие, содержащееся в методе then, будет выполнено только после успешного завершения обеих AJAX функций getData() и postData():

Пример 3

В обеих функциях нет надобности создавать объект Deferred, так как методы get() и post(), как и остальные AJAX методы содержат встроенный объект Deferred(), объект был добавлен в каждый метод AJAX в jQuery 1.5.

В 3-ем примере с помощью метода when, введенного так же в jQuery 1.5, создаётся очередь функций и методов jQuery, выполняемых в зависимости от завершения двух функций — postData()getData(), указанных в качестве параметров метода when().

Метод when обязательно должен принимать функции или методы на основе объекта Deferred(), в ином случае, очередность выполнения методов не будет соблюдена. Согласно официальной документации, если в качестве параметров метода when будет передана функция, не содержащая объект Deferred(), методы, следующие за when будут выполнены немедленно. При этом количество параметров метода when не ограничено.

Так как объект Deferred() встроен во все методы AJAX, вы можете использовать его для создания множественных обработчиков AJAX событий. В следующем примере установлены три обработчика complete() для одного объекта jqXHR.

Пример 4

Вспомогательный метод done может устанавливать функцию обратного вызова и принимать в качестве её параметров значения возвращаемые функциями, переданными в качестве аргументов в метод when, например, ниже оба AJAX запроса, при успешном их выполнении передадут объекты jqXHR в функцию обратного вызова done. После этого Вы можете обращаться в методе done к объектам AJAX запросов обычными способами.

Пример 5

Объект Deffered и методы анимации в jQuery

В предыдущих методах не были раскрыты все возможности объекта Deferred(). В методах анимации вместе с объектом допустимо использовать сопутствующие методы — faildonethenresolveresolveWithrejectrejectWith.

В следующем примере указан способ применения объекта Deferred(), когда, вновь созданные методы jDefferedIn иjDefferedOut, являясь аргументами метода when, используются для создания отсроченного метода then. Обратите особое внимание на инициализацию объекта Deferred(), чтобы выполнение определенных методов могло быть отслежено, необходимо указывать внутри функции обратного вызова метод resolve, который в свою очередь информирует о завершении функции, через метод promise():

Пример 6

Чтобы исключить действие объекта необходимо использовать метод reject() или rejectWith(). В следующем примере метод reject() отменяет дальнейшее использование объекта Deferred(), однако, в этом случае не сработает метод then, так не все методы, указанные в методе when, будут содержать объект Deferred(), вместо него сработает метод fail.

Пример 7

В случае с отклонением (reject()) будет выведено сообщение на консоль, указанное в методе fail(), если же вообще удалить объект Deferred() из функции hideDiv, то будет выполнен метод then, не дожидаясь завершения анимации в функции showDiv, вследствие того, что не все методы указанные в параметрах метода when являются объектамиDeferred(). Что убедится в этом, удалите из функции hideDiv() весь объект Deferred() и сопутствующие ему методы, а скорость анимации увеличте до 5 с.

Метод fail() может принимать несколько аргументов, которыми могут быть либо единичная функция, либо массив функций. Метод fail() выполняется только в случае использования методов отмены объекта Deferred()deferred.reject() или deferred.rejectWith().

Используя объект Deferred(), появилась возможность передавать через ключевое слово this дополнительные данные, с помощью методов resolveWith и rejectWith, ниже в метод done передаётся массив, для каждого из двух созданных объектов Deferred(), для первого объекта будет выведено сообщение «Массив с именем: Alex», для второго “Массив с именем: Pete”.

Пример 8

В следующем примере данные будут передаваться по истечении 5 секундной анимации в метод done():

Пример 9

Поэкспериментируйте с rejectWith(), но не забудьте добавить метод fail(), так как с rejectWith() метод thenне сработает.

Заключение

На этом всё с основными изменениями в jQuery 1.5. О других изменениях, таких как добавление новых методов $.sub(),$.parseXML(), а так же о расширенных возможностях AJAX, я напишу в следующих статьях!

Источник: Объект jQuery Deferred | JavaScript | Временно.нет.

Объект jQuery Deferred
Метки: