Deferred對接口的設計別出心裁,不是常規的直接定義的,我們可以看tuples這個數組的定義。
Deferred自身則圍繞這三組數據進行更高層次的抽象
? 觸發回調函數列表執行(函數名)
? 添加回調函數(函數名)
? 回調函數列表(jQuery.Callbacks對象)
? Deferred最終狀態(第三組數據除外)
var tuples = [ // action, add listener, listener list, final state ["resolve", "done", jQuery.Callbacks("once memory"), "resolved"], ["reject", "fail", jQuery.Callbacks("once memory"), "rejected"], ["notify", "progress", jQuery.Callbacks("memory")] ]
這里抽象出2組陣營:
1組:回調方法/事件訂閱
done、fail、progress
2組:通知方法/事件發布
resolve、reject、notify、resolveWith、rejectWith、notifyWith
Tuples元素集,其實是把相同有共同特性的代碼的給合并成一種結構,然后來一次處理。
jQuery.each(tuples, function(i, tuple) { //代碼請看右邊代碼區域 })
對于Tuples的3條數據集是分2部分處理的:
第一部分將回調函數存入
promise[ tuple[1] ] = list.add;
其實就是給promise賦予3個回調函數。
promise.done = $.Callbacks("once memory").add promise.fail = $.Callbacks("once memory").add promise.progressl = $.Callbacks("memory").add
如果存在Deferred最終狀態,默認會預先向doneList,failList中的list添加三個回調函數。
if (stateString) { list.add(function() { state = stateString; }, tuples[i ^ 1][2].disable, tuples[2][2].lock); }
這里有個小技巧:
i ^ 1 按位異或運算符
所以實際上第二個傳參數是1、0索引對調了,所以取值是failList.disable與doneList.disable。
通過stateString有值這個條件,預先向doneList,failList中的list添加三個回調函數,分別是:
doneList : [changeState, failList.disable, processList.lock] failList : [changeState, doneList.disable, processList.lock]
? changeState 改變狀態的匿名函數,deferred的狀態,分為三種:pending(初始狀態), resolved(解決狀態), rejected(拒絕狀態);
? 不論deferred對象最終是resolve(還是reject),在首先改變對象狀態之后,都會disable另一個函數列表failList(或者doneList);
? 然后lock processList保持其狀態,最后執行剩下的之前done(或者fail)進來的回調函數。
所以第一步最終都是圍繞這add方法:
? done/fail/是list.add也就是callbacks.add,將回調函數存入回調對象中。
第二部分很簡單,給Deferred對象擴充6個方法:
? resolve/reject/notify 是 callbacks.fireWith,執行回調函數;
? resolveWith/rejectWith/notifyWith 是 callbacks.fireWith 隊列方法引用。
最后合并promise到Deferred。
promise.promise( deferred ); jQuery.extend( obj, promise );
所以最終通過工廠方法Deferred構建的異步對象帶的所有的方法了,return內部的deferred對象了。
請驗證,完成請求
由于請求次數過多,請先驗證,完成再次請求
打開微信掃碼自動綁定
綁定后可得到
使用 Ctrl+D 可將課程添加到書簽
舉報