fire()
call. Apparently, the jQuery team decided to cut the code a bit by removing the “unnecessary / rarely used” features to save on the weight of the library. This is a small excursion into the history of Callbacks, but then I will describe only the functions currently available and at the end I will write a small possible improvement to this object. flags
parameter is optional and allows you to set the parameters of the object, the possible values ​​of the parameter we consider below. var callbacks = $.Callbacks();
callbacks
object, we can now add callbacks
functions to the list, delete them, call, call again (if this was not forbidden when creating the object), check the status of the object (whether there was already a call or not) using such object methods as add()
, remove()
, fire()
, etc. Callbacks are executed, by the way, in the order they are added to the list.new
operator when calling it is not required (and even meaningless). if (obj instanceof $.Callbacks) { obj.add(fn); }
if (obj.fire) { obj.add(fn); }
fire
, it just depends on the context, but uses it as the execution context for callbacks from the list, i.e. in some cases this method is not just possible, but it is necessary to assign the properties of another object with a change of context. For example: var c = $.Callbacks(), obj = {}; obj.register = c.add; obj.register(function() { console.log('fired'); }); c.fire(); // output: 'fired'
Note : hereinafter, the words "call thefire()
method" means calling the callbacks from the list including thefireWith()
method.
flags
constructor is a string in which you can specify flags — options — in accordance with which the created callbacks
object will work. The following flags are supported:fire()
method will fail (as was done in the deferred object); if this flag is not specified, you can call the fire()
method several times.fire()
method (and make callbacks from the list) and immediately add the added callbacks with the appropriate parameters if they are added after calling the fire()
method (as was done in the deferred object).false
, during the current session, call fire()
. The next call to the fire()
method starts a new session of executing the list of callbacks, and they will be executed again until one of the list returns false
or ends.add
- does not lead to anything, has
- always returns false
, etc.disable()
will return true
.fire()
calls, otherwise it is equivalent to the disable()
call.This method works in detail as follows: if the memory flag is not specified or thefire()
method has never been called or the last session of callbacks was interrupted by one of them returningfalse
, then thelock()
call is equivalent to thedisable()
call (this is what inside) and callingdisabled()
in this case returnstrue
, otherwise only subsequentfire()
calls will be blocked - they will neither lead to callbacks, nor change the execution parameters of added callbacks (if the memory flag is present).
lock()
method, also returns true
after a call to disable()
.this
inside the function). args is an array (just an array) of arguments passed to the callback.fireWith()
method). Those. The call context and callback arguments will be the context and arguments of the fire()
method. var callbacks = $.Callbacks(), context = { test: 1 }; callbacks.add(function(p, t) { console.log(this.test, p, t); }); callbacks.fireWith(context, [ 2, 3 ]); // output: 1 2 3 context.fire = callbacks.fire; context.fire(2, 3); // output: 1 2 3
false
, then the callbacks object will be disabled by the disable()
method. function fn1( value ){ console.log( value ); } function fn2( value ){ fn1("fn2 says:" + value); return false; }
var callbacks = $.Callbacks(); callbacks.add( fn1 ); callbacks.fire( "foo" ); callbacks.add( fn2 ); callbacks.add( fn1 ); callbacks.fire( "bar" ); callbacks.remove( fn2 ); callbacks.fire( "foobar" ); console.log(callbacks.disabled()); /* output: foo bar fn2 says:bar bar foobar foobar false */
var callbacks = $.Callbacks( "once" ); callbacks.add( fn1 ); callbacks.fire( "foo" ); callbacks.add( fn2 ); callbacks.add( fn1 ); callbacks.fire( "bar" ); callbacks.remove( fn2 ); callbacks.fire( "foobar" ); console.log(callbacks.disabled()); /* output: foo true */
var callbacks = $.Callbacks( "memory" ); callbacks.add( fn1 ); callbacks.fire( "foo" ); callbacks.add( fn2 ); callbacks.add( fn1 ); callbacks.fire( "bar" ); callbacks.remove( fn2 ); callbacks.fire( "foobar" ); console.log(callbacks.disabled()); /* output: foo fn2 says:foo foo bar fn2 says:bar bar foobar foobar false */
var callbacks = $.Callbacks( "unique" ); callbacks.add( fn1 ); callbacks.fire( "foo" ); callbacks.add( fn2 ); callbacks.add( fn1 ); callbacks.fire( "bar" ); callbacks.remove( fn2 ); callbacks.fire( "foobar" ); console.log(callbacks.disabled()); /* output: foo bar fn2 says:bar foobar false */
fn1
function was ignored. var callbacks = $.Callbacks( "stopOnFalse" ); callbacks.add( fn1 ); callbacks.fire( "foo" ); callbacks.add( fn2 ); callbacks.add( fn1 ); callbacks.fire( "bar" ); callbacks.remove( fn2 ); callbacks.fire( "foobar" ); console.log(callbacks.disabled()); /* output: foo bar fn2 says:bar foobar foobar false */
fn2
interrupts the execution chain, because returns false
. var callbacks = $.Callbacks( "once memory" ); callbacks.add( fn1 ); callbacks.fire( "foo" ); callbacks.add( fn2 ); callbacks.add( fn1 ); callbacks.fire( "bar" ); callbacks.remove( fn2 ); callbacks.fire( "foobar" ); console.log(callbacks.disabled()); /* output: foo fn2 says:foo foo false */
fire()
worked and the addition of new callbacks led to their immediate execution with the parameters of the first fire()
. var callbacks = $.Callbacks( "once memory unique" ); callbacks.add( fn1 ); callbacks.fire( "foo" ); callbacks.add( fn2 ); callbacks.add( fn1 ); callbacks.fire( "bar" ); callbacks.remove( fn2 ); callbacks.fire( "foobar" ); console.log(callbacks.disabled()); /* output: foo fn2 says:foo foo false */
fn1
twice, the second time adding this function to the list worked, because with the specified flag once after the callbacks are executed, the list is cleared, and the memory flag indicates that subsequent additions of callbacks will lead to their immediate execution without being placed on the list, and since the list is empty, the addition of any function is always unique. But this flag will play its role when you try to add several callbacks at once, among which there are duplicate ones, if in the previous code you change the 4th line as shown below, then fn2
still be executed only once (and without the unique flag, three times): callbacks.add( fn2, fn2, fn2 );
var callbacks = $.Callbacks( "once memory stopOnFalse" ); callbacks.add( fn1 ); callbacks.fire( "foo" ); callbacks.add( fn2 ); callbacks.add( fn1 ); callbacks.fire( "bar" ); callbacks.remove( fn2 ); callbacks.fire( "foobar" ); console.log(callbacks.disabled()); /* output: foo fn2 says:foo true */
false
blocked all further callbacks, and if there was a flag once, the callbacks object was turned off altogether.fire()
method, and instead use the callbacks object itself as a function. To do this, we write the following function: (function($, undefined){ $.FCallbacks = function(flags, fns) { var i = $.type(flags) === 'string' ? 1 : 0, callbacks = $.Callbacks(i ? flags : undefined); callbacks.add(Array.prototype.slice.call(arguments, i)) return $.extend(callbacks.fire, callbacks, { fcallbacks: true }); }; })(jQuery);
function fn1(p1, p2) { console.log('fn1 says:', this, p1, p2); } function fn2(p1, p2) { console.log('fn2 says:', this, p1, p2); } var callbacks = $.FCallbacks('once', fn1, rn2); callbacks.add(fn2); callbacks(2, 3);
add()
.$.ajax()
method, which by its nature is nothing but an add-on for a certain Deferred - the developers improved the code, removed it separately from the $.ajax()
main code (to be able to reuse and simplify testing) and decided, why not publish this code (give access to library users to it and document it) - it turned out $.Deferred
.$.Deferred
is initially two ( done()
and fail()
), and now three (+ more progress()
) add-ons over Callbacks, which was made as internal code $.Deferred
. And again, the developers improved and separated this code from $.Deferred
, implementing the latter through $.Callbacks
(by the way, the $.Deferred
source code became much clearer and more readable).$.ajax()
, know that you are using $.Deferred
, which means $.Callbacks
. This is an example of real use.Source: https://habr.com/ru/post/135821/
All Articles