Callbacks – это крутой объект. Он позволяет составлять списки функций обратного вызова, а также даёт бразды правления над ними. Работать с ним проще нежели с Deferred, в нём нет разделения на позитивный и негативный сценарии. Лишь стек функций, который будет выполнен по команде fire():
Если открыть консоль и запустить скрипт выше, то в результате получите что-то типа такого:
>>>
Go first
Go second
— А в чём сила, брат?
— В аргументах.
По умолчанию вы можете прямо из консоли вызывать метод fire() снова и снова, и будете получать один и тот же результат раз за разом. А можно задать поведение Callbacks через флаги:
флаг
описание
once
все функции будут вызваны единожды (аналогично как в объекте Deferred)
memory
сохранять значение с последнего вызова fire(), и скармливать его в ново-зарегистрированные функции обратного вызова, и лишь потом обрабатывает новое значение (в Deferred именно так)
unique
список функций обратного вызова фильтруется по уникальности
stopOnFalse
как только какая-нибудь функция вернёт «false», процесс запуска остановится
Наверное, будет лучше с примерами, вот once:
varC=$.Callbacks("once");C.add(function(msg) {console.log(msg +" first")});C.add(function(msg) {console.log(msg +" second")});C.fire("Go");C.fire("Again"); // не даст результата, только Go
>>>
Go first
Go second // без флага, этой строчки не было бы
Again first
Again second
Пример с уникальностью unique прост до безобразия:
varC=$.Callbacks("unique");varfunc=function(msg) {console.log(msg +" first")};C.add(func);C.add(func); // эта строка не повлияет на результатC.fire("Go"); // только Go first
>>>
Go first
Флаг stopOnFalse:
varC=$.Callbacks("stopOnFalse");C.add(function(msg) {console.log(msg +" first");returnfalse; // вот он – роковой false});C.add(function(msg) { console.log(msg +" second"); });C.fire("Go"); // только Go first
>>>
Go first
Перечисленные флаги можно комбинировать и получать интересные результаты, а можно не получать, а лишь посмотреть на следующий пример. Вот страничка для работы:
// машинкаvar $car =$('#car').show();// наш стек командvarC=$.Callbacks();
Добавьте команды по передвижению автомобиля в произвольном порядке и количестве. Для этого следует запустить перечисленные ниже скрипты (никаких изменений с машинкой до запуска метода fire() не будет):
C.add(function(speed) {$car.queue(function() { // поворот вниз, ставим в очередь с анимацией$(this).css("transform","rotate(-90deg)").dequeue(); });$car.animate({top:"+=800"}, speed); // едем вниз});
C.add(function(speed) {$car.queue(function() { // поворот налево, ставим в очередь с анимацией$(this).css("transform","rotate(0deg)").dequeue(); });$car.animate({left:"-=400"}, speed); // едем влево});
C.add(function(speed) {$car.queue(function() { // поворот вправо, ставим в очередь с анимацией$(this).css("transform","rotate(180deg)").dequeue(); });$car.animate({left:"+=400"}, speed); // едем вправо});
C.add(function(speed) {$car.queue(function() { // поворот наверх ставим в очередь с анимацией$(this).css("transform","rotate(90deg)").dequeue(); });$car.animate({top:"-=400"}, speed); // едем вверх});
Поехали!
// запускаем «программу»// в качестве параметра передаём скорость движенияC.fire(400);
Из истории: объект «Deferred» отпочковался от метода $.ajax() в результате рефакторинга jQuery версии 1.5. Шло время, появлялись новые версии jQuery, и вот новый виток рефакторинга – результатом стало отделение «Callbacks» от «Deferred» в версии 1.7, таким образом в текущей версии библиотеки метод $.ajax() работает с объектом «Deferred», который является надстройкой над «Callbacks». Дабы не вносить путаницу в терминологию, я использую определение «Deferred Callbacks» и при работе с «Callbacks», ибо колбэков много, и каждый раз уточнять, что я говорю именно «о том самом» — дело достаточно утомительное.