語義,實乃的兩段代碼之間沒有真正的區別。消息在調用初始函數後的某個時間提供給回調函數。
從設計的角度來看,人們傾向於承諾,因爲他們通常會導致更容易執行代碼。在回調處理某些長時間運行的函數的結果時,尤其如此。考慮以下兩個慢速運行的功能:
var slowlyReturn1 = function (callback) {
window.setTimeout(callback.call(1), 1000);
}
var slowlyReturn2 = function (callback) {
window.setTimeout(callback.call(2), 1000);
}
使用這兩個長期運行的功能的結果
寫代碼是很毛毛:
slowlyReturn1(function(resultOf1) {
slowlyReturn2(function(resultOf2) {
console.log("results were: " + resultOf1 + " and " + resultOf2);
})
});
請注意,在長鏈各個環節運行功能導致另一個嵌套級別。隨着承諾的代碼,你往往不會有這樣的問題:
var slowlyReturn1 = function() {
var d = $.Deferred();
window.setTimeout(function() { d.resolve(1) }, 1000);
return d.promise();
}
var slowlyReturn2 = function() {
var d = $.Deferred();
window.setTimeout(function() { d.resolve(2) }, 1000);
return d.promise();
}
var resultOf1;
slowlyReturn1().then(function(r) {
resultOf1 = resultOf1;
return slowlyReturn2();
}).then(function(resultOf2) {
console.log("results were: " + resultOf1 + " and " + r);
});
而且,與承諾的代碼,也往往是關注清晰分離。執行慢速運行操作的代碼不知道結果將如何使用:它只是返回表示延遲結果並讓調用方處理它的內容。
這你對付它的一個很好的應用設計環繞異常處理。緩慢運行的操作可能是.resolve()
的承諾,但他們也可能在出現問題的地方出現.reject()
。這可以拒絕使用.fail()
如下處理:
slowRunningOperations().then(function() {
...
...
... handle success
...
...
}).fail(function() {
...
... handle failure
...
...
})
這裏,運行慢的操作的調用者並不關心錯誤,它可以簡單地忽略它們。
有承諾編程其他幾個好處:
支持的承諾提供了一種方法來治療這兩種常規功能和返回一個承諾以同樣的方式的功能大多數圖書館。他們通常通過提供名爲when()
的功能來實現此目的。這爲測試承諾代碼提供了一個非常好的方法,或者允許將慢速函數更改爲影響調用者的promise-returning-one w/o。
支持承諾的大多數庫還提供了使用承諾模擬更傳統的控制流的功能。例如,Q庫提供allSettled(list)
,它接受承諾列表並返回一個承諾,該承諾在列表中的所有承諾都完成時解決。
也就是說,正如另一個答案所述,承諾會帶來一點開銷。如果你沒有進行強化鏈接或錯誤處理,或者嚴格按照控制流使用回調,那麼只需傳遞函數即可。
來源
2014-06-18 01:54:02
ctt
Promises在自己的實現中使用回調函數,但也支持更多的功能,例如處理程序的鏈接,異步完成/錯誤通知的標準化接口等等。這有點像說功能和OOP之間有什麼區別,一個是低層構造 - 另一個是使用相同低層構造的更多功率機制,但也支持更多功能和可擴展性。承諾的真正威力來自您需要進行序列化或協調的多個異步操作。 – jfriend00