? ? ? 最近在用node.js寫一個工具,發(fā)現(xiàn)自己對Promise的模式還是不太了解蹂窖,于是打算重溫《深入淺出node.js》智听,不過精讀的時候發(fā)現(xiàn)該書沒有隨書代碼的下載,而且書中關(guān)于Promise的部分代碼交代不夠清楚怜珍,可能影響讀者理解端蛆,本人花了一些時間將代碼整理出來,建議讀者對照書籍查看酥泛。
1.Promise/A
? ? ? 不清楚Promise模式定義的同學(xué)請自行百度今豆,書中使用Promise/A模式以點帶面介紹Promise。在介紹完P(guān)romise/A的抽象定義后柔袁,通過繼承node的events模塊來完成了一個簡單的實現(xiàn)呆躲。
需要注意兩點 :
? ? 1)Promise繼承自events,其中繼承的方式采用了寄生組合式繼承(詳見《Javascript高級程序設(shè)計》第三版)
? ? 2)then方法繼續(xù)返回Promise對象,以實現(xiàn)鏈式調(diào)用
為了完成整個流程捶索,還需要觸發(fā)執(zhí)行這些回調(diào)函數(shù)的地方插掂,實現(xiàn)這些功能的對象通常被稱為Deferred,即延遲對象
現(xiàn)在我們對一個典型的響應(yīng)對象進行封裝
我們將其改造為Promise/A模式
原書在18行代碼出有錯誤腥例,已調(diào)整辅甥。。從上面的代碼可以看出燎竖,Deferred主要是用于內(nèi)部璃弄,用于維護異步模型的狀態(tài);Promise則作用于外部构回,通過then()方法暴露給外部以添加自定義邏輯夏块。
2.Promise中的多異步協(xié)作
在Promise的介紹中說過,主要解決的是單個異步操作中存在的問題纤掸〔Ψ觯回到我們的難點,當我們需要處理多個異步調(diào)用時茁肠,又該如何處理呢患民?
這里我們保持Promise代碼不變
Deferred代碼增加了all()方法,all()方法將兩個單獨的Promise重新抽象組合成一個新的Promise
我們以多次訪問文件為例垦梆,只有所有異步操作成功匹颤,這個異步操作才算成功仅孩,一旦其中一個異步操作失敗,整個異步操作就失敗印蓖。
3.Promise的同步操作
在Node中辽慕,網(wǎng)絡(luò)庫是完全異步的,無法在編程層面實現(xiàn)像其他語言那般的同步調(diào)用赦肃。因此解決同步調(diào)用的代碼可能就變成了
理想的編程體驗應(yīng)當是前一個的調(diào)用結(jié)果作為下一個調(diào)用的開始溅蛉,是傳說中的鏈式調(diào)用,下面進行改造
Promise代碼:
Deferred代碼:
調(diào)用代碼:
可以看到最后一個then的調(diào)用主體已經(jīng)完全轉(zhuǎn)交給了readFile2中的promise對象他宛,通過這種方式船侧,我們完全可以寫出更優(yōu)雅的同步代碼。