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