前言
在js中使用回调函数是很常见的。但是当触发一个事件时需要同时执行多个回调函数时,我们可能就需要一个队列来把这些回调函数存放起来,当事件触发时按照队列的先进先出原则依次调用这些回调函数。在jQuery中就是使用$.Callbacks这个工具方法来管理回掉函数队列的。
1 function fn1(){
2 console.log(1);
3 }
4 function fn2(){
5 console.log(2);
6 }
7 var callbacks = $.Callbacks();
8 callbacks.add(fn1);
9 callbacks.add(fn2);
10 callbacks.fire();// 1 2
当回调函数在不同的作用域也可以添加在一个队列中。
1 function fn1(){
2 console.log(1);
3 }
4 var callbacks = $.Callbacks();
5 !function(){
6 function fn2(){
7 console.log(2);
8 }
9 callbacks.add(fn2);
10 }();
11 callbacks.add(fn1);
12 callbacks.fire();// 2 1
回调对象的方法
在jQuery源码中,所有的回调函数存在数组变量list中。
1、add:向list中添加回调函数。可以是一个或多个回掉函数参数,多个回掉函数也可以用数组的形式。
1 function fn1(){
2 console.log(1);
3 }
4 function fn2(){
5 console.log(2);
6 }
7 function fn3(){
8 console.log(3);
9 }
10 var callbacks = $.Callbacks();
11 callbacks.add(fn1);
12 callbacks.add(fn2);
13 callbacks.add(fn3);
14 callbacks.fire(); // 1 2 3
2、remove:从list中移除回调函数。可以是一个或多个回掉函数参数,多个回掉函数也可以用数组的形式。
1 callbacks.remove(fn1, fn2);
2 callbacks.fire(); // 3
3、has:无参数判断list中是否有回调函数,有参数判断该参数对应的回调函数是否在list中。
1 console.log(callbacks.has()); // true
2 console.log(callbacks.has(fn1)); // true
4、empty:清空回调对象的list。
5、disable:禁用回调对象,所有操作都不能执行。
6、disabled:判断回调对象是否被禁用。
7、lock:锁住,后面的fire和fireWith不能执行。
8、locked:判断是否是已被锁定的回调列表。
9、fireWith:
1 var name = 'window';
2 var person = {name: 'hum'};
3 function fn1(){
4 console.log(this.name);
5 }
6 var callbacks = $.Callbacks();
7 callbacks.add(fn1);
8 callbacks.fireWith(window); // window
9 callbacks.fireWith(person); // hum
1 var name = 'window';
2 var person = {name: 'hum'};
3 function fn1(value){
4 console.log(value + this.name);
5 }
6 function fn2(value1, value2){
7 console.log(value1+ value2 + this.name);
8 }
9 var callbacks = $.Callbacks();
10 callbacks.add(fn1);
11 callbacks.add(fn2);
12 callbacks.fireWith(window, ['window:', 'age:']); // window:window window:age:window
13 callbacks.fireWith(person, ['person:']); // person:hum person:undefinedhum
10、fire:fire方法调用了fireWith(this)方法,fireWith方法最终调用了源码中的fire私有函数
11、fired:判断回调列表是否已经被调用过(调用fire或fireWith方法)
回调对象的flag
$.Callbacks对象的flag决定了回调对象的类型。
1 function fn1(){
2 console.log(1);
3 }
4 function fn2(){
5 console.log(2);
6 }
7 var callbacks = $.Callbacks('once');
8 callbacks.add(fn1);
9 callbacks.fire(); // 1
10 callbacks.add(fn2);
11 callbacks.fire(); // 不会触发
2、memory:记忆当次调用fire和fireWith,在遇到下次调用fire或fireWith之前,只要回调对象调用add方法都能执行,遇到下次调用时才会计算队列的remove、empty、add关系。
1 function fn1(){
2 console.log(1);
3 }
4 function fn2(){
5 console.log(2);
6 }
7 var callbacks = $.Callbacks('memory');
8 callbacks.add(fn1);
9 callbacks.fire(); // 1 2
10 callbacks.add(fn2);
11
12 callbacks.fire(); // 1 2 2
13 callbacks.empty();
14 callbacks.add(fn2);
15
16 callbacks.fire(); // 2 1
17 callbacks.add(fn1);
3、unique:去从。
1 function fn1(){
2 console.log(1);
3 }
4 function fn2(){
5 console.log(2);
6 }
7 var callbacks = $.Callbacks('unique');
8 callbacks.add(fn1);
9 callbacks.add(fn2);
10 callbacks.add(fn2);
11 callbacks.fire(); // 1 2
4、stopOnFalse:当有一个对调函数返回false时,后面的回调都不会执行了。
1 function fn1(){
2 console.log(1);
3 return false;
4 }
5 function fn2(){
6 console.log(2);
7 }
8 var callbacks = $.Callbacks('stopOnFalse');
9 callbacks.add(fn1);
10 callbacks.add(fn2);
11 callbacks.fire(); // 1
这四种类型可以组合使用,用空格隔开。
1 function fn1(){
2 console.log(1);
3 return false;
4 }
5 function fn2(){
6 console.log(2);
7 }
8 var callbacks = $.Callbacks('once memory');
9 callbacks.fire();
10 callbacks.add(fn1); // 1 2
11 callbacks.add(fn2);
12 callbacks.fire(); // 没有输出