jQuery Callbacks Memory Flag Explained

This article explains the purpose and functionality of the memory flag in jQuery's $.Callbacks() utility. It covers how this flag stores the most recent arguments passed to a callback list and causes newly attached functions to execute immediately using those cached values, providing a clear comparison between standard callback behavior and memory-enabled lists.

What the 'memory' Flag Does

By default, a jQuery $.Callbacks() list only executes functions that are present in the list at the exact moment .fire() is called. Any functions added via .add() after the list has fired remain dormant until .fire() is called a second time.

When initialized with the 'memory' flag—$.Callbacks('memory')—the object remembers the arguments from the most recent .fire() execution. Whenever a new callback function is subsequently added to the list using .add(), it executes immediately, receiving those stored arguments.

Code Comparison

Default Behavior (Without 'memory')

var callbacks = $.Callbacks();

function fn1(val) {
    console.log("fn1: " + val);
}

function fn2(val) {
    console.log("fn2: " + val);
}

callbacks.add(fn1);
callbacks.fire("foo"); // Output: fn1: foo

callbacks.add(fn2);    // Nothing happens; fn2 is simply queued.

In the default scenario, fn2 does not run because it was registered after .fire("foo") occurred.

Behavior With 'memory'

var callbacks = $.Callbacks('memory');

function fn1(val) {
    console.log("fn1: " + val);
}

function fn2(val) {
    console.log("fn2: " + val);
}

callbacks.add(fn1);
callbacks.fire("foo"); // Output: fn1: foo

callbacks.add(fn2);    // Output: fn2: foo (Executes immediately)

Because the memory flag is active, callbacks.add(fn2) immediately triggers fn2 using "foo" as its argument. If .fire("bar") is called later, both fn1 and fn2 will run with the new value "bar", updating the cached memory state.

Practical Use Cases

The primary use case for the memory flag is managing state-based events rather than simple point-in-time actions.

This behavior is the foundation for jQuery's $.Deferred() and Promise implementations. When an asynchronous operation resolves, any success or error handlers attached after the operation has already completed must still run. The memory flag ensures that newly attached .then() or .done() callbacks execute with the original resolution values, regardless of when they are added to the chain.