Understanding the jQuery Callbacks Once Flag
The $.Callbacks() utility in jQuery provides a
multi-purpose tool for managing callback functions, allowing developers
to queue, fire, and manage custom functions efficiently. When the
'once' flag is passed during initialization, it
fundamentally alters the callback list by ensuring that the callbacks
can only be executed a single time, preventing any subsequent firing of
the list.
Single Execution Behavior
By default, a standard jQuery Callbacks list can be fired repeatedly.
Every time .fire() or .fireWith() is invoked,
all attached functions run sequentially. When the 'once'
flag is supplied ($.Callbacks('once')), the list executes
only on the first call to .fire(). Any subsequent calls to
.fire() are completely ignored, and the callbacks will not
run again.
let callbacks = $.Callbacks('once');
callbacks.add(function(val) {
console.log("Triggered:", val);
});
callbacks.fire("First call"); // Logs: "Triggered: First call"
callbacks.fire("Second call"); // Ignored: does nothingHandling Late Additions
When using only the 'once' flag without the
'memory' flag, any function added using .add()
after the list has already fired will not be executed. Because the list
has completed its single allowed run, new functions simply remain
uncalled unless the callback object is configured with complementary
flags.
Combining 'once' with the 'memory' Flag
The 'once' flag is frequently paired with the
'memory' flag ($.Callbacks('once memory')).
This specific combination enables a unique behavior:
- The list as a whole can still only be manually triggered via
.fire()once. - Any callbacks added via
.add()after the initial firing will be executed immediately using the arguments supplied during that initial fire event.
This pattern is the foundational mechanism behind jQuery's
$.Deferred() and Promise implementations, where an
operation resolves only once, but any handlers registered after
resolution must still execute with the original resolved values.
Memory Management and State
Once fired, an isolated 'once' callback list essentially
locks its state. The .fired() method will permanently
return true. Internally, jQuery tears down and clears the
callback list after execution to free up memory resources, preventing
detached function references from lingering in memory.