jQuery.Callbacks()
Method
Example
Adding a callback function to the $.Callbacks list
$(function () {
function fn1( value ) {
alert( value );
}
function fn2( value ) {
fn1("fn2 says: " + value);
return false;
}
var callbacks = $.Callbacks();
callbacks.add( fn1 );
// Output: foo!
callbacks.fire( "foo!" );
callbacks.add( fn2 );
// Output: bar!, fn2 says: bar!
callbacks.fire( "bar!" );
})
Definition and Usage
$.Callbacks() refers to a multi-purpose callback function list object, providing a powerful way to manage callback function queues.
Tip: $.Callbacks is used internally by jQuery, such as for .ajax, $.Deferred, etc., to provide foundational functionality. It can also be used in similar components, such as custom plugins.
Syntax
Parameter | Description |
---|---|
flags | Optional. String type. A space-separated optional list of flags to change the behavior of the callback list. |
More Examples
Below is an example of using .remove() to remove a specific callback from the callback list
Example
$(function () {
function fn1( value ) {
alert( value );
}
function fn2( value ) {
fn1("fn2 says: " + value);
return false;
}
var callbacks = $.Callbacks();
callbacks.add( fn1 );
// Output: foo!
callbacks.fire( "foo!" );
callbacks.add( fn2 );
// Output: bar!, fn2 says: bar!
callbacks.fire( "bar!" );
callbacks.remove( fn2 );
// Only outputs foobar, fn2 has been removed.
callbacks.fire( "foobar" );
})
Supported Flags Parameter
The flags parameter is an optional parameter for $.Callbacks(), structured as a space-separated list of flags to change the behavior of the callback list (e.g., $.Callbacks('unique stopOnFalse')). The available flags are:
Parameter | Description |
---|---|
once | Ensures the callback list only executes once. |
memory | Caches the last fired parameters, and when add() is called, immediately invokes the newly added callback with the cached parameters. |
Below is an example of $.Callbacks('once')
Example
$(function () {
function fn1( value ) {
alert( value );
}
function fn2( value ) {
fn1("fn2 says: " + value);
return false;
}
var callbacks = $.Callbacks('once');
callbacks.add( fn1 );
callbacks.fire( "foo" );
callbacks.add( fn2 );
callbacks.fire( "bar" );
callbacks.remove( fn2 );
callbacks.fire( "foobar" );
/* Only outputs: foo */
})
Below is an example of $.Callbacks('memory')
Example
$(function () {
function fn1( value ) {
alert( value );
}
function fn2( value ) {
fn1("fn2 says: " + value);
return false;
}
var callbacks = $.Callbacks('memory');
callbacks.add( fn1 );
callbacks.fire( "foo" );
callbacks.add( fn2 );
callbacks.fire( "bar" );
callbacks.remove( fn2 );
callbacks.fire( "foobar" );
/* Outputs:
foo
fn2 says: foo
bar
fn2 says: bar
foobar
*/
})
Below is an example of $.Callbacks('unique')
Example
$(function () {
function fn1( value ) {
alert( value );
}
function fn2( value ) {
fn1("fn2 says: " + value);
return false;
}
var callbacks = $.Callbacks('unique');
callbacks.add( fn1 );
callbacks.fire( "foo" );
callbacks.add( fn1 ); // repeat addition
callbacks.add( fn2 );
callbacks.fire( "bar" );
callbacks.remove( fn2 );
callbacks.fire( "foobar" );
/* Outputs:
foo
bar
fn2 says: bar
foobar
*/
})
Below is an example of $.Callbacks('stopOnFalse')
Example
$(function () {
function fn1( value ) {
alert( value );
return false;
}
function fn2( value ) {
fn1("fn2 says: " + value);
return false;
}
var callbacks = $.Callbacks('stopOnFalse');
callbacks.add( fn1 );
callbacks.fire( "foo" );
callbacks.add( fn2 );
callbacks.fire( "bar" );
callbacks.remove( fn2 );
callbacks.fire( "foobar" );
/* Outputs:
foo
bar
foobar
*/
})
$.Callbacks() supports setting multiple flags (identifiers) at once, which has an accumulative effect, similar to "&&".
Example
$(function () {
function fn1( value ) {
alert( value );
return false;
}
function fn2( value ) {
fn1("fn2 says: " + value);
return false;
}
var callbacks = $.Callbacks('unique memory');
callbacks.add( fn1 );
callbacks.fire( "foo" );
callbacks.add( fn1 ); // repeat addition
callbacks.add( fn2 );
callbacks.fire( "bar" );
callbacks.add( fn2 );
callbacks.fire( "baz" );
callbacks.remove( fn2 );
callbacks.fire( "foobar" );
/* Outputs:
foo
fn2 says: foo
bar
fn2 says: bar
baz
fn2 says: baz
foobar
*/
})
The $.Callbacks method can also be separated, for example:
Example
$(function () {
function fn1( value ) {
alert( value );
}
var callbacks = $.Callbacks(),
add = callbacks.add,
remove = callbacks.remove,
fire = callbacks.fire;
add( fn1 );
fire( "hello world" );
remove( fn1 );
/* Outputs: hello world */
})
$.Callbacks, $.Deferred, and Pub/Sub
The general idea behind pub/sub (observer pattern) is to promote loose coupling and efficient communication in applications. Observers, also known as subscribers, point to the subject being observed. The publisher notifies subscribers when an event occurs.
As a demonstration of the components created by $.Callbacks(), you can implement a Pub/Sub system using just the callback function list. By treating $.Callbacks as a message queue, you can implement message publishing and subscribing as follows:
Example
$(function () {
function fn1( value ) {
alert( value );
return false;
}
function fn2( value ) {
fn1("fn2 says: " + value);
return false;
}
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;
};
var topic = jQuery.Topic( "example" );
topic.subscribe( fn1 );
topic.publish( "foo" );
topic.subscribe( fn2 );
topic.publish( "bar" );
topic.unsubscribe( fn2 );
topic.publish( "foobar" );
/* Outputs:
foo
fn2 says: foo
bar
fn2 says: bar
foobar
*/
})
{
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!");
/* Output:
hello world!
fn2 says: hello world!
woo! mail!*/
})
Further improvements using $.Deferreds can ensure that publishers can only publish notifications to subscribers when specific tasks are completed (or resolved). See the example code below:
## Example
$(function () { function fn1(value) { alert(value); return false; }
function fn2(value) {
fn1("fn2 says: " + value);
return false;
}
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;
};
// Subscribe to mailArrived notifications
$.Topic("mailArrived").subscribe(fn1);
// Create a new Deferred object
var dfd = $.Deferred();
// Define a new topic (not publishing directly)
var topic = $.Topic("mailArrived");
// When the Deferred is resolved, publish a notification to subscribers
dfd.done(topic.publish);
/* This will delay the message being passed to the subscribers,
it integrates complex programs (such as waiting for an
Ajax call to complete) so that the message is actually only
published once. */
// Resolve.
dfd.resolve("Published!");
})
---
[jQuery Miscellaneous Methods](jquery-ref-misc.html)