Callbacks是jQuery 1.7引入的方法,用于管理一组有相同方法参数的回调函数。Callbacks除了可以向数组一样可以添加、删除、清空回调,还提供了几种特殊模式。在不同模式下,回调函数的生命周期和执行顺序稍有不同。
生成回调列(Callbacks)
var callbacks = $.Callbacks(flags);
参数falgs是字符串,用于标示Callbacks的模式,比如在”once stopOnFalse”模式下,回调最多只执行一遍,如果执行过程中某个回调返回false,同样也中断回调列的执行。
那么jQuery.Callbacks使用场景在哪里?
在很多时候需要控制一系列的函数顺序执行。那么一般就需要一个队列函数来处理这个问题
我们看一段代码
function Aaron(List, callback) { setTimeout(function() { var task = List.shift(); task(); //执行函数 if (task.length > 0) { //递归分解 setTimeout(arguments.callee, 1000) } else { callback() } }, 25) } Aaron([function(){ alert('a') },function(){ alert('b') }],function(){ alert('callback') }) 分别弹出 ‘a’ , ‘b’ ,’callback’
传入一组函数参数,靠递归解析,分个执行,其实就是靠setTimeout可以把函数加入到队列末尾才执行的原理
*****但是这样写,是不是很麻烦?*****
我们换成jQuery提供的方式
var callbacks = $.Callbacks(); callbacks.add(function() { alert('a'); }) callbacks.add(function() { alert('b'); }) callbacks.fire(); //输出结果: 'a' 'b'
是不是便捷很多了,代码又很清晰,所以它是一个多用途的回调函数列表对象,提供了一种强大的方法来管理回调函数队列。
同时还提供几个便捷的处理参数
once: 确保这个回调列表只执行( .fire() )一次(像一个递延 Deferred).
memory: 保持以前的值,将添加到这个列表的后面的最新的值立即执行调用任何回调 (像一个递延 Deferred).
unique: 确保一次只能添加一个回调(所以在列表中没有重复的回调).
stopOnFalse: 当一个回调返回false 时中断调用
var callbacks = $.Callbacks('once'); callbacks.add(function() { alert('a'); }) callbacks.add(function() { alert('b'); }) callbacks.fire(); //输出结果: 'a' 'b' callbacks.fire(); //未执行
once的作用是使callback队列只执行一次
Callbacks模式
默认模式:回调列中的回调默认可多次执行,回调函数可重复添加。但在执行过程中,新添加的回调不执行。
once:列中的每一个回调最多执行一遍,执行完成之后,回调函数列被清空。
memory:在回调执行过程中,添加新的回调,则新的回调也可以执行。
Unique:同一个回调不能重复添加。
stopOnFalse:如果某个回调如果返回false,那么后面的回调都不会再执行,即使在memory模式下也如此。
var callbacks = $.Callbacks("once memory");
回调执行顺序
回调保存在数组中,然后通过for循环遍历,所以列中的回调按照被添加的顺序依次执行,最后添加的一般最后执行。
// Fire the items on the list var foo = function( value ) { console.log( "foo:" + value ); }; // Add another function to the list var bar = function( value ){ console.log( "bar:" + value ); }; var callbacks = $.Callbacks(); callbacks.add( foo ); callbacks.add( bar); callbacks.fire("hello"); // output: foo: hello // output: bar: hello
唯一例外的情况是如果标记是memory,如果之前fire()被调用过,那么新的回调被add()添加之后会立刻使用前一个fire的参数执行一遍。但add()之前被fire()调用过的回调,如果没有使用fire()或fireWith(),不会马上再执行一遍。
其它关键点
回调函数中调用Callbacks的fire()或fireWith()
有一种情况是在回调中又调用了Callbacks对象的fire()或fireWith()方法,这种情况该怎么办?
jquery是这样做的:在回调中调用fire()或fireWith(),Callbacks对象只是保存了fire()或fireWith()的参数,并没有立即执行列中的回调。等callbacks中的所有回调执行完之后,再用新的参数重新执行Callbacks对象中的所有回调。
注意:如果标记是once,回调中执行fire或fireWith()无效。
function fn1( value ){ console.log( value ); if (value == "bar!") return false; callbacks.fire("bar!"); } function fn2( value ){ console.log( "fn2 says: " + value); } var callbacks =$.Callbacks("stopOnFalse"); callbacks.add( fn1 ); callbacks.add( fn2 ); // Outputs: foo! // Outputs: fn2 says:foo! // Outputs: bar! callbacks.fire("foo!" );
调用callbacks.disable()之后,callbacks无法再被enabled
调用disable()之后,回调函数列就被清空了,此时使用fire或fireWith都不会有任何响应。因此,Callbacks没有提供enable方法,因为所有回调已经被清空了,没有再enable的必要。
callbacks.lock()
回调列被锁死,再调用callbacks.fire()或callbacks.fireWith()都将失效。
如果是在回调中调用了callbacks.lock(),则有一点需要注意:
callbacks有memory标记:当前fire()或fireWith()方法中没有执行的回调会继续执行,但回调中的callbacks.fire()和callbacks.fireWith()都不会再起作用。
callbacks无memory标记:所有回调全部被清空,也就是说后面的回调都不再执行。
奇怪的是Callbacks没有提供unlock方法,也就是说,一旦被locked,Callbacks就永久失去了调用fire()或fireWith()的能力。
Atas ialah kandungan terperinci jQuery中的Callbacks应用的重点在哪里?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!