我們可以藉由觀看jQuery的源始碼(jquery-1.11.3.js)來較清楚地了解Deferred到底做了什麼事及怎麼實現的,以更好的運用Deferred及其相關API。
在了解Deferred之前,我們可以先來了解Callbacks這個類別。在這邊用形象的方式來了解Callbacks的運作方式。
Callbacks可以被當成是一個佇列式的列隊(先進先出,FIFO),我們可以把想要做的function傳進列隊中(add()),並在想要的時候觸發列隊中的function執行(fire() or fireWith()),在這邊是一次執行所有的function,雖然有照順序開始執行,但並無法保證一個function執行完才執行下一個(例如要花時間的異步函式)。
而Deferred則是利用Callbacks的性質來實作的,基本上就是預先將異步函式做完時要執行的回調函式先放到列隊中,並執行異步函式,等異步函式執行完後手動決定要觸發列隊裡函式並執行的時機。
jQuery的Callbacks有以下常用的API function:
- $.Callbacks([flags]) : 創建並返回一個Callbacks類別。
- flags : 可選,可以接受多個,用空格的String來表示,例如有以下幾種:
- once:
- 列隊只能被觸發一次(fire)。
- memory:
- 列隊觸發後,一有函式放進(add)列隊會被馬上執行。
- unique:
- 列隊中的同樣函式(指的是其參考一樣的 reference)再一次觸發時只會被執行一次。
- flags : 可選,可以接受多個,用空格的String來表示,例如有以下幾種:
- Callbacks.add(callbacks) : 將callbacks函式放進Callbacks列隊中。
- Callbacks.fire([arguments]) : 觸發列隊執行其中的函式。
- arguments : 可選,可傳入參數給列隊中各函式當input value。
- Callbacks.fireWith([context] [, arguments]) : 跟fire()相似,也是觸發列隊執行其中的函式,不過可以指定上下文(context),即函式中的this指誰。
- Callbacks.disable() : 將callback列隊disable掉,即之後不能在做fire()之類的呼叫(呼叫了也不會有行為)
-
$.Callbacks() :
function funGenerator(funId){ return function(){ console.log(funId); } } var callbacks = $.Callbacks(); callbacks.add(funGenerator('f1')); callbacks.add(funGenerator('f2')); callbacks.fire(); //output : f1 ,f2 callbacks.fire(); //output : f1 ,f2
-
$.Callbacks('once') :
function funGenerator(funId){ return function(){ console.log(funId); } } var callbacks = $.Callbacks('once'); callbacks.add(funGenerator('f1')); callbacks.add(funGenerator('f2')); callbacks.fire(); //output : f1 ,f2 callbacks.fire(); //no output
-
$.Callbacks('memory') :
function funGenerator(funId){ return function(){ console.log(funId); } } var callbacks = $.Callbacks('memory'); callbacks.add(funGenerator('f1')); callbacks.add(funGenerator('f2')); callbacks.fire(); //output : f1 ,f2 callbacks.add(funGenerator('f3')); //output : f3
沒有留言 :
張貼留言