前言
jQuery.Callbacks是jquery在1.7版本之後加入的,是從1.6版中的_Deferred物件中抽離的,主要用來進行函數佇列的add、remove、fire、lock等操作,並提供once 、memory、unique、stopOnFalse四個option進行一些特殊的控制。
功能介紹
jq的Callbacks模組主要是為其他模組提供服務的,他就像一個溫柔的小女人,在背後默默地付出。 Deferred就像一個巨人,在jq中那麼的突出,但在內部,他受到Callbacks的服務。
Callbacks的幾個狀態:
once -- 回呼函數只執行一次
-- 狀態記憶,主要用於Deferred中
stopOnFalse -- 遇到return false 終止回呼清單繼續執行
我自己實作的Callbacks的幾個簡單的方法
has -- 回呼這樣做:
var cb = Callback('memory once') // 得到一个拥有记忆功能并只执行一次的回调模块
由於我們需要基於一定狀態來得到不同的實例,我們可以確定,我們需要一個儲存狀態的物件
var callbackState = {}
,我們要怎麼記錄這兩個狀態呢,在這裡,仿jq來寫的一個函數來實現,如下:
var createCallbackState = function (options) { var states = options.split(' ') var obj = {} for (var i = 0; i < states.length; i++) { obj[states[i]] = true } return obj }
var Callback = function (options) { var state = callbackState[options] //获取状态模式 if (!state) { callbackState[options] = state = createCallbackState(options) } var list = [], // 回调函数列表 memory, // 存储是否为 记忆状态 has = function (fn) { for (var i = 0; i < list.length; i++) { if (list[i] === fn) { return true } } return false }, add = function () { var i = 0, args = arguments, len = args.length for (; i < len; i++) { if (state.unique && has(args[i])) { // 如果是unique状态下并回调列表已经拥有该函数,则不添加 continue } list.push(args[i]) } }, fire = function (context, args) { var i = 0, len = list.length, item for (; i < len; i++) { item = list[i] if (item.apply(context,args) === false && state.stopOnFalse) { //如果函数运行返回false,并且是stopOnFalse状态,终止循环 break; } } } return { add: function () { add.apply(null,arguments) // 如果memory模式并且已经拥有了memory信息,接着出发函数 if (state.memory && memory) { fire(memory[0], memory[1]) list = [] } }, fire: function (context, args) { // 如果memory模式,并且list是空,代表触发在添加前,保存memory信息 if (state.memory && !list.length) { memory = [context, args] return } fire(context,args) if (state.once) { this.clear() } }, has: function (fn) { return has(fn) }, clear: function () { list = [] } } }
add.apply(null,arguments)
// 如果memory模式并且已经拥有了memory信息,立刻触发函数 if (state.memory && memory) { fire(memory[0], memory[1]) list = [] }
var cb = Callback('memory') // 得到记忆功能的回调模块 cb.fire() // 触发回调队列 cb.add(fn) //添加回调函数,自动执行了! function fn () { console.log('fn') }
// 如果memory模式,并且list是空,代表触发在添加前,保存memory信息 if (state.memory && !list.length) { memory = [context, args] return }