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