Очередь функций обратного вызова jQuery.Callbacks

В jQuery 1.7 появился новый объект для создания и управления очередью колбеков – jQuery.Callbacks. Он был предложен на рассмотрение команде разработчиков еще 6 месяцев назад. Менеджер было успешно опробован и пошел в релиз. На его основе был переписан jQuery.Deferred, который в свою очередь лежит в основе системы колбеков jQuery.ajax.

Конструктор jQuery.Callbacks можно вызывать как с оператором new, так и без него. В результате будет создан объект с несколькими методами: add(), remove(), fire(), disable() и др.

В параметры конструктору можно передать один или несколько флагов. От их наличия и сочетания будут меняться параметры, с которыми вызываются колбеки, и поведение очереди в целом. Рассмотрим их подробнее.

Вызов конструктора с различными флагами

Очередь, созданная без флагов, ведет себя так как если бы это была, например, очередь используемая в событиях.

var c = $.Callbacks();
c.add(function (val) {
    console.log("1: " + val);
});
c.fire("foo");
c.add(function (val) {
    console.log("2: " + val);
});
c.fire("bar");

После выполнения этого кода в консоль будет выведено:

1: foo

1: bar

2: bar

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

Флаг once указывает на то, что метод fire() будет выполнен только один раз для такой очереди.

var c = $.Callbacks("once");
c.add(function (val) {
    console.log("1: " + val);
});
c.fire("foo");
c.add(function (val) {
    console.log("2: " + val);
});
c.fire("bar");

В этом коде в консоль выведутся результаты работы только первой функции.

1: foo

Флаг memory предписывает запоминать последнее значение, с которым был вызван метод fire() и автоматически вызывать вновь добавляемые колбеки с этим значением.

var c = $.Callbacks("memory");
c.add(function (val) {
    console.log("1: " + val);
});
c.fire("foo");
c.add(function (val) {
    console.log("2: " + val);
});
c.fire("bar");

Когда вызывается метод fire("foo"), то второго колбека еще нет в очереди. Но как только он будет добавлен, так сразу вызовется с параметром "foo".

1: foo

2: foo

1: bar

2: bar

Флаги можно комбинировать. Так одновременное использование once и memory даст результат аналогичный по свой сути работе jQuery.Deferred – вызов колбеков будет сделан только один раз, а новые колбеки сразу будут вызываться при их добавлении.

var c = $.Callbacks("once memory");
c.add(function (val) {
    console.log("1: " + val);
});
c.fire("foo");
c.add(function (val) {
    console.log("2: " + val);
});
c.fire("bar");

1: foo

2: foo

Если будет установлен флаг unique, то одна и та же функция обратного вызова в очередь будет добавлена только один раз.

И последний флаг stopOnFalse прерывает выполнение очереди, если какой-либо колбек вернет значение false.

Применение

Благодаря этому менеджеру, например, в плагинах можно легко добавить поддержку не одного колбека, а сразу цепочки нескольких функций. Или же с помощью него можно уменьшить связанность различных компонент.