整個$.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 可將課程添加到書簽
舉報