memory:保持以前的值,將添加到這個列表的后面的最新的值立即執行調用任何回調 (像一個遞延 Deferred)。
回調函數是從異步隊列Deferred分離出來的,所以很多的接口設計都是為了契合Deferred接口,memory用的很多,這個緩存的設計這里提及一下
主要是用來實現deferred的異步收集與pipe管道風格的數據傳遞的,具體在Deferred有詳解,這里大概了解下作用范圍。
memory這個有點不好理解,我們還是通過列子說明下,看下面的代碼:
var cbs = Callbacks('once'); cbs.add(fn1); cbs.fire('foo'); cbs.fire('foo'); function fn1(val) { console.log('fn1 says ' + val); } function fn2(val) { console.log('fn2 says ' + val); } function fn3(val) { console.log('fn3 says ' + val); } var cbs = $.Callbacks('memory'); cbs.add(fn1); cbs.fire('foo'); console.log('..........') cbs.add(fn2); cbs.fire('bar'); console.log('..........') cbs.add(fn3); cbs.fire('aaron');
結果可以看出,我們在執行cbs.add(fn2);的時候,此時除了把fn2添加到了回調隊列之外而且還立刻執行了這個方法,唯一的區別就是,參數是用的之前的。所以解釋就叫“保持以前的值”。
fn1 says foo .......... fn2 says foo fn1 says bar fn2 says bar .......... fn3 says bar fn1 says aaron fn2 says aaron fn3 says aaron
所以這個memory
設計需要解決的問題就是:
1:如何取到上一個參數
2:add后如何執行
看看我們實現的代碼:
function Callbacks(options) { var list = []; var self; var firingStart; var memory; function _fire(data) { memory = options === 'memory' && data; firingIndex = firingStart || 0; firingStart = 0; firingLength = list.length; for (; list && firingIndex < firingLength; firingIndex++) { list[firingIndex](data) } } self = { add: function(fn) { var start = list.length; list.push(fn) if (memory) { firingStart = start; //獲取最后一值 _fire(memory); } }, fire: function(args) { if (list) { _fire(args) } } } return self; }
首先add之后要能觸發fire的動作,所以我們把fire作為內部的一個私有方法實現_fire,比較合邏輯,這樣外部的fire只是一個門面方法的調用。
私有變量memory緩存這上一個參數的屬性,我們靠firingStart用來定位最后通過add增加的回調數據的索引。在遍歷的時候直接通過firingStart的起始索引定位,然后傳遞memory的參數,而且實現這種“保持以前的值”的設計。
請驗證,完成請求
由于請求次數過多,請先驗證,完成再次請求
打開微信掃碼自動綁定
綁定后可得到
使用 Ctrl+D 可將課程添加到書簽
舉報