您可以用得最多無論是在這種情況下(有一個行爲差)。第一個是標準的承諾功能,可以與任何承諾庫一起工作。
Promise.try()
是由Bluebird庫專門實現的功能,不屬於任何我知道的標準過程。
使用Promise.try()
的原因是,如果您有一個函數返回承諾,但生成該承諾的代碼也可能會導致同步異常。由於該異常不在任何承諾處理程序中,因此您可能會混合使用錯誤處理。某些代碼執行路徑可能會導致返回的承諾被解析或拒絕,而其他代碼執行路徑可能會引發異常。爲了安全地進行編碼,你必須同時響應這個承諾,並在代碼中放置一個try/catch塊,這個代碼很笨拙。
Promise.try()
只是一種自動捕捉任何異常並將它們變爲拒絕的手段(類似於.then()
處理程序中發生的情況)。
在這兩種情況下,Promise.try()
不會以這種方式讓您受益,因爲new Promise()
回調已捕獲異常,並將它們變爲拒絕,以便您的功能已在您那裏完成。你可以在這裏看到演示:http://jsfiddle.net/jfriend00/wLov9844/
藍鳥文檔提供了這個例子顯示了利益更加清晰:
function getUserById(id) {
return Promise.try(function() {
if (typeof id !== "number") {
// Courtesy of Promise.try() this exception will be turned
// into a returned promise that is rejected with the
// exception as the reason
throw new Error("id must be a number");
}
return db.getUserById(id);
});
}
getUserById().then(successFn, errFn);
採用Promise.try()
這裏可以確保getUserById()
總是會返回一個承諾,即使該方法內部的代碼會同步引發異常。這簡化了getUserById()
的使用,因爲您可以始終響應承諾並且不必使用您自己的異常處理程序。
沒有Promise.try()
,你可以自己編寫同樣的事情,像這樣(趕在函數內的所有可能的同步異常):
function getUserById(id) {
try {
if (typeof id !== "number") {
throw new Error("id must be a number");
}
return db.getUserById(id);
} catch(e) {
return Promise.reject(e);
}
}
getUserById().then(successFn, errFn);
或者,你可以像這樣的代碼時:
function getUserById(id) {
if (typeof id !== "number") {
throw new Error("id must be a number");
}
return db.getUserById(id);
}
try {
getUserById().then(successFn, errFn);
} catch(e) {
errFn(e);
}
據推測,你可以看到Promise.try()
在某些情況下可以簡化事情。
僅供參考,您的第一個例子中,使用的是無效的語法。你可以這樣做:
reject(throw new Error('error'));
我假設你的意思是這樣的:
reject(new Error('error'));
雖然我不認爲這是真的,你在問,也Promise.try()
會是什麼自動返回已解決的承諾,如果您沒有自己回覆承諾。由於通過第一個示例的一條路徑不能解決或拒絕,因此這會導致您的兩個示例有所不同。
鬆散相關:[Promise.reject vs throw error](http://stackoverflow.com/q/28703241/1048572)。你不應該使用'new Promise'構造函數,除非你真的在做一些異步的事情。這裏的正確方法是'返回Promise.reject(...)'(或使用'Promise.try' /'Promise.method')。 – Bergi