整个$.Callbacks的源码很少,它是一个工厂函数,使用函数调用(非new,它不是一个类)创建对象,它有一个可选参数flags用来设置回调函数的行为,对外的接口也就是self的返回。
jQuery.Callbacks()的API列表如下:
callbacks.add() :回调列表中添加一个回调或回调的集合。 callbacks.disable() :禁用回调列表中的回调。 callbacks.disabled() :确定回调列表是否已被禁用。 callbacks.empty() :从列表中删除所有的回调。 callbacks.fire() :用给定的参数调用所有的回调。 callbacks.fired() :访问给定的上下文和参数列表中的所有回调。 callbacks.fireWith() :访问给定的上下文和参数列表中的所有回调。 callbacks.has() :确定列表中是否提供一个回调。 callbacks.lock() :锁定当前状态的回调列表。 callbacks.locked() :确定回调列表是否已被锁定。 callbacks.remove() :从回调列表中的删除一个回调或回调集合。
源码结构:
jQuery.Callbacks = function(options) { options = typeof options === "string" ? (optionsCache[options] || createOptions(options)) : jQuery.extend({}, options); //实现代码 fire = function() {} self = { add: function() {}, remove: function() {}, has: function(fn) {}, empty: function() {}, disable: function() {}, disabled: function() {}, lock: function() {}, locked: function() {}, fireWith: function(context, args) {}, fire: function() {}, fired: function() {} }; return self; };
整个结构要分三部分:
☑ Options参数缓存
☑ 内部fire触发器的设计
☑ 外部
参数的缓存设计
Callbacks是可以是接受的字符串的组合传参数,可以使用空格分割,代码如下:
var opts = 'unique memory'; var object = {} jQuery.each(opts.match(/\S+/g) || [], function(_, flag) { object[flag] = true; });
这样的操作其实是不需要重复的,所以我们可以设计一个缓存池,用来储存重复的操作:
var optionsCache = {}; function createOptions(options) { var object = optionsCache[options] = {}; jQuery.each(options.match(rnotwhite) || [], function(_, flag) { object[flag] = true; }); return object; }
所以我们传递参数的时候,如果参数是字符串,我们可以直接从optionsCache缓存中去查找:
options = typeof options === "string" ? ( optionsCache[ options ] || createOptions( options ) ) : jQuery.extend( {}, options );
接口的设计:
通过学习了观察者模式的思路,我们知道callback需要在内部维护着一个list的队列数组,用于保存订阅的对象数据。同时也需要提供了add、remove、fire等订阅、发布、删除类似的接口。
那么我们代码是不是很简单是就是把订阅对象给push给内部list列表?
实现思路就是: 构建一个存放回调的数组,如var list = []
,通过闭包使这条回调数组保持存在。添加回调时,将回调push进list,执行则遍历list执行回调。
后面几节我们会通过简单的模拟实现去剖析设计的思路。
请验证,完成请求
由于请求次数过多,请先验证,完成再次请求
打开微信扫码自动绑定
绑定后可得到
使用 Ctrl+D 可将课程添加到书签
举报