Подтвердить что ты не робот

Когда я буду использовать 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)

но это тоже не очень помогает.

  • Я не понимаю документацию?

  • Если это желаемая функциональность, то какие примеры применимы там, где это полезно.

4b9b3361

Ответ 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, вместо того, чтобы пытаться заставить вашу волю выполнить реализацию "Отложенная".