jQuery.Callbacks()是在版本1.7中新加入的。它是一个多用途的回调函数列表对象,提供了一种强大的方法来管理回调函数队列。
那么jQuery.Callbacks使用场景在哪里?
在很多时候需要控制一系列的函数顺序执行。那么一般就需要一个队列函数来处理这个问题
我们看一段代码


传入一组函数参数,靠递归解析,分个执行,其实就是靠setTimeout可以把函数加入到队列末尾才执行的原理
*****但是这样写,是不是很麻烦?*****
我们换成jQuery提供的方式


是不是便捷很多了,代码又很清晰,所以它是一个多用途的回调函数列表对象,提供了一种强大的方法来管理回调函数队列。
同时还提供几个便捷的处理参数
<code>once</code>: 确保这个回调列表只执行( .fire() )一次(像一个递延 Deferred).
<code>memory</code>: 保持以前的值,将添加到这个列表的后面的最新的值立即执行调用任何回调 (像一个递延 Deferred).
<code>unique</code>: 确保一次只能添加一个回调(所以在列表中没有重复的回调).
<code>stopOnFalse</code>: 当一个回调返回false 时中断调用


once的作用是使callback队列只执行一次
OK,我们大概知道这个是干嘛用的了,可以开始上正菜了。
根据jQuery.Callbacks()的API
提供一下几种方法:


我们看官网提供的demo


可以将上述两个方法作为回调函数,并添加到 <code>$.Callbacks</code> 列表中,并按下面的顺序调用它们:


这样做的结果是,当构造复杂的回调函数列表时,将会变更很简单。可以根据需要,很方面的就可以向这些回调函数中传入所需的参数。
上面的例子中,我们使用了 <code>$.Callbacks()</code> 的两个方法: <code>.add()</code> 和 <code>.fire()</code>。 .add() 可以向回调函数列表中添加新的回调函数,fire() 可以向回调函数中传递参数,并执行回调函数。
设计思想:
先看官网的demo这个列子,涉及到了 add 与 fire方法,熟悉设计模式的童鞋呢,一眼就看出,其实又是基于发布订阅的观察者模式的设计了
pub/sub (观察者模式) 的背后,总的想法是在应用程序中增强松耦合性。并非是在其它对象的方法上的单个对象调用。一个对象作为特定任务或是另一对象的活动的观察者,并且在这个任务或活动发生时,通知观察者。观察者也被叫作订阅者(Subscriber),它指向被观察的对象,既被观察者(Publisher 或 subject)。当事件发生时,被观察者(Publisher)就会通知观察者(subscriber)
作为 <code>$.Callbacks()</code> 的创建组件的一个演示,只使用回调函数列表,就可以实现 Pub/Sub 系统。将 <code>$.Callbacks</code> 作为一个队列
我来模拟下常规最简单的实现



Observable.add(function() {
alert(1)
})
Observable.fire(function() {
alert(2)
Observable.fire(); // 1, 2

构建一个存放回调的数组,如this.callbacks= [] 添加回调时,将回调push进this.callbacks,执行则遍历this.callbacks执行回调。
也弹出1跟2了,实际上jQuery.callbacks是如何处理的呢?
我们看源码
整个$.Callbacks的源码很少,它是一个工厂函数,使用函数调用(非new,它不是一个类)创建对象,它有一个可选参数flags用来设置回调函数的行为。、
对外的接口也就是self的返回
self上的add源码
源码
其中有一段代码要单独拿出来


add方法
callbacks.add( callbacks )
callbacks
一个函数,或者一个函数数组,用来添加到回调列表。
如果是数组会递归调用私有的add函数 list.push( arg );
发现没,设计的原理上其实跟上面发的简单模式 大同小异
fire方法
外观模式 self.fire –> self.fireWith –> fire
最终执行代码是内部私有的fire方法了
最终处理的代码
其实就是拿出list中保存的回调函数,执行罢了,所以整个设计的原理,还是符合我们开始设想的
具体的实现
<code>$.Callbacks( "once" )</code>
确保这个回调列表只执行( .fire() )一次(像一个递延 Deferred).


在fire中调用了 self.disable(); 方法
<code>$.Callbacks( "memory" )</code>
保持以前的值,将添加到这个列表的后面的最新的值立即执行调用任何回调 (像一个递延 Deferred).


在调用 add() 方法时,如果这时 callbacks队列 满足 fired && firing = false(真执行完毕) && memory(需要在构造函数指定),那么add() 进去的回调函数会立即执行,而这个 add 进去的回调函数调用时的参数存储在 memory 变量中。memory 变量用于存储最后一次调用 callbacks.fireWith(...) 时所使用的参数 [context, arguments]。
<code>$.Callbacks( "unique" )</code>
确保一次只能添加一个回调(所以在列表中没有重复的回调)


****注意add方法默认不去重,比如这里fn1添加两次,fire时会触发两次****
这里处理很简单
在添加的到处理队列时候,判断一下即可
<code>$.Callbacks( "stopOnFalse" )</code>:
当一个回调返回false 时中断调用


附源码:


jQuery.Callbacks() 比较简单,也没什么难点
jQuery.Callbacks() 方法的核心是 fire() 方法,将该 fire() 方法作为私有方法被封装在函数中不可直接访问
因此像 memory、firing、fired 这些状态对于外部上下文来说是不可更改的
还有需要注意的是,如果回调函数中使用了 this 对象,可以直接用这个 this 来访问self对象的公有API。当然,也可以用 fireWith() 自己指定 this 的引用对象。
jQuery.Callbacks()的核心思想是 Pub/Sub 模式,建立了程序间的松散耦合和高效通信。
本文转自艾伦 Aaron博客园博客,原文链接:http://www.cnblogs.com/aaronjs/p/3342344.html,如需转载请自行联系原作者