Javascript 的世界裡頭充滿了 callback,從其他語言進入 Javascript 的世界常會頭昏,甚至會有點排斥這樣的特性。本篇文章介紹 Deferred 物件的基礎用法,避免程式在做順序任務的處理時難以維護,在模組化的程式設計中,是很重要也很常用到的技巧。
Callback function
假設我們有一個 query 的 function,也許是 ajax,也許是 sql query,總之它接受命令做完回傳 callback
因此我們可以很簡單的呼叫
但假設我們要依序執行 query 的話,例如 task1 -> task2 -> task3,很自然地就會寫成這樣:
function call function
這樣的問題就是巢狀的 function 裡頭要做的事情越來越複雜,就會將 function 寫成一大包,到最後很難維護。所以很直覺的就將要做的事情拆成 function來處理,例如:
把 function 拆開看起來就不會有巢狀越寫越深的問題了,但是會遇到問題是:
- 若你的 function 散落各處,就會很難 trace 程式碼。
- function 與 function 之間的依賴性。越複雜的依賴性會讓程式日後難以維護。
那麼如何利用 Deferred 物件?
首先我們用 Deferred 方式把 query 包起來
接著我們就可以這樣呼叫
看起來沒什麼了不起,那接著來寫順序的任務吧:
XDXDXD,翻白眼翻到外太空,當然不是這樣的,這樣還是在寫巢狀的程式。
Deferred and pipe
我們需要用pipe來串聯我們的任務:
這樣看起來就精簡多了,而且也很容易看懂 task 之間的順序關係。
Library
在瀏覽器環境中,可以直接使用 jQuery Deferred,若你不需要 jQuery,可以用 stand alone Deferred。
另外在 node 環境中,可以使用 node-deferred。
Reference
本範例程式碼:https://gist.github.com/blackbing/a9dad5c141f51b65b650
不只 pipe,Deferred 還有很多其他的用法,有興趣深入了解的話可以參考: