create-date: 2013-10-16
jQuery 中的 Callbacks 对象是众多模块的基础,例如 Deferred 对象。
Callbacks 是用于处理回调函数的列表对象,它支持添加、移除、触发,和禁用回调函数。
关于该对象的作用,这篇博客讲的很清楚。
flag 处理
Callbacks 的一个特点是它支持多种 flag,不同的 flag 代表一种特定功能:
- once:确保回调函数只触发一次
- memory:当回调函数触发完毕后,再次添加新的回调函数,会使用此前使用的参数来立即触发新回调函数
- unique:同样的回调函数只能添加一次
- stopOnFalse:当回调函数返回 false 时终止后续回调的触发
在 callbacks.js 的开头位置就是用于处理 flag 的代码。
var optionsCache = {};
// 将字符串格式的选项转成对象格式并保存在缓存对象中
function createOptions( options ) {
var object = optionsCache[ options ] = {};
jQuery.each( options.match( core_rnotwhite ) || [], function( _, flag ) {
object[ flag ] = true;
});
return object;
}
core_rnotwhite 是 core.js 中定义的 /\S+/g,除此之外没有什么内容需要介绍。
细节
Callbacks 应该是 jQuery 中相对很好读的部分,因此我就不准备一句句介绍,说些我在阅读过程中产生困惑的地方。
源码中有 firing 这个变量存在,它表示当前列表是否在执行回调函数,在执行前,它的值为 true,全部回调函数执行完毕后,它的值设置为 false。
最开始的时候我的思路受了限制,以为回调函数触发的时候,根本无法去操作回调函数列表,因此对源码中 add 和 remove 方法对 firing 的判断表示不能理解,但后来我想到了:如果在回调函数中去操作列表,不是正好符合判断 firing 的情况吗?
var callbacks = $.Callbacks();
callbacks.add( function A() {
console.log('A')
callbacks.add(function B() {
console.log('B')
});
});
callbacks.add( function C() {
console.log('C')
});
callbacks.fire();
当 A 函数触发时,它向队列里添加了一个函数 B,由于队列存在顺序问题,这个函数 B 应该晚于函数 C 的触发。这时只需要修改触发回调函数列表长度 firingLength 即可。
对于 Callbacks 我想说的只有这些。