Deferred是前端解決異步操作的一種編程范式,后來出現的Promise規范更是讓其普適性大大提高。不過Promise規范也存在分岐。現在最流行的是Promise/A規范。
Promise/A大致是這樣的:一個帶有then方法的對象,它擁有三個狀態,pending,fulfilled, rejected。一開始是pending,執行then 方法后,當其回調被執行,會進入fulfiled或rejected狀態。
then方法可傳入兩個函數,一個是成功時執行,一個是失敗時執行,分別叫做onFulfilled, onRejected。then還有第3個參數叫做onNotify,它不會改變對象的狀態。這三個函數都是可選的,非函數時會被忽略掉。
乍一看,沒什么。主菜在后面。then方法在添加了onFufilled或onRejected會返回一個新的Promise對象。這樣一來,就能形成一個Promise鏈。
顯然,jQuery Deferred並不滿足后面的那個條件。
后來人們在Promose/A那粗糙的准則上添加更多的細節,形成了Promise/A+, http://promises-aplus.github.io/promises-spec/,重點見Requirements與Notes。
Notes還着重提到為了防止Promise鏈還沒有形成就被用戶觸發回調,強烈要求使用setTimeout,setImmediate,process.nextTick等異步API來提供回夠的構建時間。這思路其實與著名的JSDeferred如出一轍,或者它本來就是從JSDeferred那里剽來的。
此外,大家在實現Promise/A+時,漸漸達成一些共識,添加了all, any等方法,來並歸結果或處理競態狀態。現在市面上有三大Promise/A+庫, Q, RSVP , when。其中,Q的微縮版被整進angular.js, RSVP 被整進ember.js ,angular, ember 我后面會重點介紹,都是著名的MVVM庫。微軟出品的WinJs MVVM框架,也內置一個Promise模塊。
jQuery Deferred雖然不標准,但它的出現已表明Deferred/Promise這種異步范式的重要了。
隨着avalon“王的三柱臣”之一mmRequest工作的展開,我需要一個更精致的底層異步庫。這就是mmDeferred的由來。
現在mmDeferred放在github上,擁有完整的示例與API文檔,歡迎大家關注與fork
有關異步庫的重要性,可以看我以前寫的兩篇文章:
或看屈屈寫的這篇文章,是介紹when.js的應用的。
由於Deferred是如此重要的,ecma262下一版已提議內置此對象了,詳見這里