Когда я буду использовать JQuery.Callbacks?
Я просматривал новые вещи, добавленные в jQuery 1.7, и я видел, что теперь у них есть jQuery.Callbacks() http://api.jquery.com/jQuery.Callbacks/.
В документации показано, как использовать jQuery.callbacks(), но не применимые примеры того, когда я захочу их использовать.
Кажется, вы можете добавить/удалить обратные вызовы из списка обратных вызовов, и вы можете сделать jQuery.callbacks(). fire (args), но это просто отключает ВСЕ обратные вызовы в этом списке. Возможно, мне что-то не хватает, но это не очень полезно.
В моей голове, когда я впервые увидел эту новую функциональность, я подумал, что вы сможете использовать ее с парами ключ/значение. Тогда это обеспечит простой способ управления функциями обратного вызова в одном месте приложения. Что-то вроде
$.callbacks.add("foo", myFunction);
а затем, например, если бы я хотел вызвать этот обратный вызов в конце моей функции, я мог бы сделать что-то вроде
$.callbacks().fire("foo", args);
Однако не похоже, что вы можете отключить определенные обратные вызовы, вы можете только их отключить с помощью приведенных аргументов или ни одного из них.
Ближайшая вещь, которую я видел, давалась возможность предоставить функции .fire() контекст для установки свойства "this"
.fireWith(context, args)
но это тоже не очень помогает.
-
Я не понимаю документацию?
-
Если это желаемая функциональность, то какие примеры применимы там, где это полезно.
Ответы
Ответ 1
Чтобы развернуть на @Rockets ответьте немного и устраните некоторую путаницу:
Причина, по которой вам может понадобиться использовать jQuery $.Callbacks
, многогранна:
- Пользователь имеет много кода в одной функции и хочет разбить его
-
Они берут эту информацию и отправляют ее через функцию обратного вызова jQuery, которая затем позволяет им разбить свой код на более удобные для управления элементы, с которыми можно работать.
Так (например), если вы посмотрите @Rocket code:
var clickCallbacks = $.Callbacks();
clickCallbacks.add(function() { //one one function piece
//parse and do something on the scope of `this`
var c = parseInt(this.text(), 10);
this.text(c + 1);
});
clickCallbacks.add(function(id) { //add a second non-related function piece
//do something with the arguments that were passed
$('span', '#last').text(id);
});
$('.click').click(function() {
var $ele = $(this).next('div').find('[id^="clickCount"]');
clickCallbacks.fireWith($ele, [this.id]); //do two separate but related things.
});
- Теперь у вас есть несколько партий функций обратного вызова, которые вы можете теперь вызывать, когда вы считаете это необходимым, без необходимости делать так много изменений по всему вашему коду.
Ответ 2
Я вижу, что обратные вызовы полезны, когда вы обновляете разные элементы DOM с использованием одного и того же метода.
Вот дрянной пример: http://jsfiddle.net/UX5Ln/
var clickCallbacks = $.Callbacks();
clickCallbacks.add(function() {
var c = parseInt(this.text(), 10);
this.text(c + 1);
});
clickCallbacks.add(function(id) {
$('span', '#last').text(id);
});
$('.click').click(function() {
var $ele = $(this).next('div').find('[id^="clickCount"]');
clickCallbacks.fireWith($ele, [this.id]);
});
Он обновляет счетчик кликов и "последний щелчок", когда вы нажимаете на что-то.
Ответ 3
(почти) из коробки jQuery Pub/Sub system
Это IMHO самое интересное приложение, и поскольку в ответах не было четко указано (хотя некоторые из них делают намек на использование), я добавляю его в этот относительно старый пост.
NB:. Использование явно указано, например, в jQuery docs, но я думаю он был добавлен после публикации вопроса.
Pub/sub, так называемый шаблон наблюдателя, является шаблоном, который способствует свободному соединению и единой ответственности в приложении. Вместо того, чтобы иметь объекты, вызывающие непосредственно методы других объектов, объекты вместо этого подписываются на конкретную задачу или активность и уведомляются, когда это происходит. Для более подробного объяснения преимуществ использования шаблона Pub/Sub вы можете проверить Зачем использовать шаблон публикации/подписки (в JS/jQuery)?.
Конечно, это возможно с настраиваемыми событиями с использованием trigger
, .on()
и .off()
, но я нахожу jQuery.Callbacks
как a лот больше подходит для задачи, создавая более чистый код.
Вот фрагмент примера из документации jQuery:
var topics = {};
jQuery.Topic = function( id ) {
var callbacks,
method,
topic = id && topics[ id ];
if ( !topic ) {
callbacks = jQuery.Callbacks();
topic = {
publish: callbacks.fire,
subscribe: callbacks.add,
unsubscribe: callbacks.remove
};
if ( id ) {
topics[ id ] = topic;
}
}
return topic;
};
И пример использования:
// Subscribers
$.Topic( "mailArrived" ).subscribe( fn1 );
$.Topic( "mailArrived" ).subscribe( fn2 );
$.Topic( "mailSent" ).subscribe( fn1 );
// Publisher
$.Topic( "mailArrived" ).publish( "hello world!" );
$.Topic( "mailSent" ).publish( "woo! mail!" );
// Here, "hello world!" gets pushed to fn1 and fn2
// when the "mailArrived" notification is published
// with "woo! mail!" also being pushed to fn1 when
// the "mailSent" notification is published.
/*
output:
hello world!
fn2 says: hello world!
woo! mail!
*/
Ответ 4
Кажется, что $.Callbacks
началось как деталь реализации: средство для управления списками функций и вызова всех функций в данном списке с теми же аргументами. Немного, как С# многоадресные делегаты, с дополнительными функциями, такими как флаги, которые вы можете передать, чтобы настроить поведение списка.
Хорошим примером может быть то, что jQuery использует $.Callbacks
внутренне для реализации своего события ready
. bindReady()
инициализирует список обратных вызовов:
readyList = jQuery.Callbacks( "once memory" );
Обратите внимание на флаги once
и memory
, которые гарантируют, что список обратного вызова будет вызываться только один раз, а функции, добавленные после вызова списка, будут вызываться немедленно.
Затем ready()
добавляет указанный обработчик в этот список:
ready: function( fn ) {
// Attach the listeners
jQuery.bindReady();
// Add the callback
readyList.add( fn );
return this;
}
Наконец, список обратных вызовов запускается, когда DOM готов:
readyList.fireWith( document, [ jQuery ] );
Все обработчики ready
вызываются в контексте одного и того же документа с той же ссылкой на глобальный объект jQuery. Их можно назвать только один раз, а дополнительные обработчики, переданные в ready()
, будут вызываться немедленно с этого момента, все это любезно предоставлено $.Callbacks
.
Ответ 5
Я не вижу конкретного упоминания об установке контекста, но поскольку вы можете передать произвольное количество аргументов, это потенциально может быть полезно. Вы также можете сделать свое собственное соглашение, чтобы передать флаг в качестве первого аргумента и заставить слушателей немедленно возвращать false, если они не предназначены для обработки оставшегося списка аргументов.
Я встречал случаи, когда что-то вроде этого могло быть полезно, но вместо этого использовали bind() и trigger() с настраиваемыми событиями. Представьте себе какую-то систему обработки сообщений (веб-чат или почтовый клиент), где вы отправляете запрос на обслуживание новых сообщений. Одной из функций может быть установка числа в промежутке или отображение рычания, когда что-то произойдет. Другим может быть обновление сетки. С помощью триггеров вам придется запускать событие для каждого слушателя и "разворачивать" переданные аргументы из eventData, с обратными вызовами - только один огонь, а ваши слушатели - это простые функции javascript с простым списком аргументов.
Обратные вызовы не совсем революционны, но это сделает менее чистый код.
Ответ 6
Я работаю над приложением с большим количеством бизнес-логики и не менее 11 внешних сервисов. Это действительно помогает держать все в порядке, если вы можете написать свои собственные классы управления потоками и поведения, используя что-то вроде Callbacks, вместо того, чтобы пытаться заставить вашу волю выполнить реализацию "Отложенная".