JQuery.Callbacks系列一:api使用详解

JQuery.Callbacks是jQuery1.7+之后引入的,用来进行函数队列的add、remove、fire、lock等操作,并提供once、memory、unique、stopOnFalse四个option进行一些特殊的控制。既然是新加入的功能,那么就有其特定的使用场景和优势。本文主要是介绍下Callbacks相关API的使用,关于Callbacks的使用场景以及源码等将会在后续博客中进行说明。我使用的JQuery版本是1.11.1


1、创建Callbacks对象

如果要使用Callbacks的相关API,必须要先创建Callbacks对象。创建Callbacks对象的时候,可以指定参数,也可以不指定参数。不同参数值的Callbacks具有不同的功能,后面再介绍,这里只需要知道如何创建Callbacks对象即可。

// 默认方式创建callback
var callbacks = $.Callbacks();

// 4种形式的callback:once、unique、stopOnFalse、memory
var onceCallbacks = $.Callbacks('once');
var uniqueCallbacks = $.Callbacks('unique');
var stopOnFalseCallbacks = $.Callbacks('stopOnFalse');
var memoryCallbacks = $.Callbacks('memory');
还有一点需要说明:每次调用$.Callbacks()方法,返回的都是不同的Callbacks对象。即这是一个工厂方法,每次调用都会新建一个对象,对象之间是相互独立的。

var callbacks1 = $.Callbacks();
var callbacks2 = $.Callbacks();
alert(callbacks1 == callbacks2);//false


2、添加和删除回调函数

Callbacks对象其实就是一个函数队列,获得Callbacks对象之后 ,就可以向这个集合中增加或者删除函数。add和remove功能相反,函数参数是相同的,empty()删除回调列表中的所有函数。

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

 var callbacks = $.Callbacks();

 // 方式1:添加1个单独函数
  callbacks.add( fn1 );
  callbacks.add( fn2 );

// 方式2:添加多个函数
  callbacks.add(fn1,fn2);

// 方式3:添加函数数组
  callbacks.add([fn1,fn2]);

// 方式4 函数和数组混合
  callbacks.add(fn1, [fn2]);
可以看到add/remove可以支持多种类型的参数列表,我们可以根据需要自由选择。关于add有几点需要说明:
1、同一个函数可以多次通过add()添加到Callbacks中,执行的时候该函数也会多次执行。

var callbacks = $.Callbacks();
callbacks.add(fn1);
callbacks.add(fn1);

// 调用callbacks中的函数
callbacks.fire("hi!");

2、如果add()添加的是匿名函数,那么不能通过remove()删除。

var callbacks = $.Callbacks();
callbacks.add(functio(){console.log("fn1:" + value );});

// not work
callbacks.remove(functio(){console.log("fn1:" + value );});

3、如果函数fn1通过add()添加了多次,那么remove()之后,这多次添加都会被删除。

callbacks.add( fn1 );
callbacks.add( fn1 );
callbacks.add( fn2);

callbacks.fire( "foo!" );
callbacks.remove(fn1,fn2);
callbacks.fire( "foo!" );//fn1和fn2都不会再触发

4、remove一个不存在的函数没有任何效果

var callbacks = $.Callbacks();
callbacks.remove(fn1,fn2);


3、触发回调函数

通过fire或firefireWith可以调用回调列表的函数。fire()函数中的参数列表可以传递多个实参,但是不能是参数数组。

function fn(a,b) {
	console.log("a="+a);
	console.log("b="+b);
}

var callbacks = $.Callbacks();
callbacks.add(fn);
callbacks.fire(1,2);//a=1,b=2
callbacks.fire([3,4]);a=[3,4],b=undefined
fireWith的参数列表只能是数组,不能是多个参数(会报类型不匹配的错误)。

function fn(a,b) {
	console.log("a="+a);
	console.log("b="+b);
}

var callbacks = $.Callbacks();
callbacks.add(fn);

// Function.prototype.apply: Arguments list has wrong type 

callbacks.fireWith(null,[1,2]);//a=1,b=2
callbacks.fireWith(null,1,2);
fire()和fireWith()还有一个重要区别,fireWith能够改变函数执行上下文,而fire上下文固定是Callbacks对象。什么是函数执行上下文呢?其实就是函数中this到底指代哪儿对象。如果函数中么有this,那么上下文就没有什么作用。

function fn(a) {
    console.log(this); 
    console.log("a="+a); 
}

var callbacks = $.Callbacks();
callbacks.add(fn);

callbacks.fire(1);//a=1,this就是callbacks对象

var me = {"name":"aty","age":26};
callbacks.fireWith(me,[2]);//a=2,this是me


4、Callbacks对象的状态判断

判断Calllbacks对象的状态相关API有has()、disabled()、locked()、fired()。

disabled()和locked()判断Callbacks对象是否处于disabled状态或是locked状态。可以通过disable()、lock()改变Callbacks对象的状态。这个地方有点奇怪,一旦将Callbacks禁用或者锁定,那么就无法再恢复。

var callbacks1 = $.Callbacks();
callbacks1.lock();
console.log(callbacks1.locked());

var callbacks2 = $.Callbacks();
callbacks2.disable();
console.log(callbacks2.disabled());
fired()判断Callbacks对象是否调用过fire()或者fireWith()方法。只要在Callbacks对象上调用过一次fire或fireWith,fired()就会一直返回true,否则返回false。


has()的参数是一个函数,用来判断该函数是否已经存在于回调列表中,不想重复添加时很有用。

var callbacks = $.Callbacks();
callbacks.has(fn1);//false
callbacks.add(fn1);
callbacks.has(fn1);//true



5、创建Callbcks对象时的4种类型

前面我们创建Callbacks对象的时候,没有指定任何参。在jquery1.11.1版本中有once、unique、stopOnFalse、memory这4种参数值可以指定,或者是他们的组合。

var onceCallbacks = $.Callbacks('once');
//2种标志的组合
var stopOnFalseCallbacks = $.Callbacks('once stopOnFalse');

once用来确保某个回调函数至多只触发一次。

//使用once
var onceCallbacks = $.Callbacks('once');
onceCallbacks.add(fn1);
onceCallbacks.fire(1); // 打印1
onceCallbacks.fire(1); // fn不再触发

unique用来保证add()时候函数不会重复添加。

//使用unique,可以使用has判断去重,使用unique属性则更方便
var uniqueCallbacks = $.Callbacks('unique');
uniqueCallbacks.add(fn1);
uniqueCallbacks.add([fn1, fn2]); // 再次添加fn1
uniqueCallbacks.fire(2); 

stopOnFalse当某个回调函数返回false之后,那么就不再执行之后的回调函数。

// 使用stopOnFalse
function f1() {
    console.log("f1");
}
function f2() {
    console.log("f2");
    return false // 注意这里
}
function f3() {
    console.log("f3");
}
var stopOnFalseCallbacks = $.Callbacks('stopOnFalse');
stopOnFalseCallbacks.add(f1, f2, f3);
stopOnFalseCallbacks.fire();//不会触发f3

memory缓存上一次fire/fireWith时的参数值,当add()添加回调函数时,直接用上一次的参数值立刻调用新加入的回调

function fn1( value ) {
  console.log( "fn1 says:" + value );
}
 
function fn2( value ) {
  console.log( "fn2 says:" + value );
}

//使用memory
var memoryCallbacks = $.Callbacks('memory');
memoryCallbacks.add(fn1);

//第一次fire会缓存传入的参数
memoryCallbacks.fire('foo');

//fire过一次之后,以后的add都会自动调用fire,传入的参数是上次fire传入的'foo'
memoryCallbacks.add(fn2);

//此次fire的参数新传入的'bar'
//fn1 says bar
//fn2 says bar
memoryCallbacks.fire('bar');



6、lock()和disable()

这2个API使用很简单,就是将Callbacks对象置成disabled或者locked状态。这2个API源码如下:

// Have the list do nothing anymore
disable: function() {
	list = stack = memory = undefined;
	return this;
},

// Lock the list in its current state
lock: function() {
	stack = undefined;
	if ( !memory ) {
		self.disable();
	}
	return this;
},
可以看到,如果创建Callbacks对象的时候没有使用memory标志,那么lock和disable没有什么区别。而且lock和disable都是单向操作,一旦调用就无法在复原。后面博客再继续讲解lock和disable的区别以及使用场景。


你可能感兴趣的:(JQuery.Callbacks系列一:api使用详解)