[英]Bluebird Promise: Is is possible to have multiple reject() in new Promise(function (resolve, reject)?
[英]Bluebird.JS Promise: new Promise(function (resolve, reject){}) vs Promise.try(function(){})
我什么時候應該使用哪個? 以下是相同的嗎?
新的Promise()示例:
function multiRejectExample(){
return new Promise(function (resolve, reject){
if(statement){
console.log('statement 1');
reject(throw new Error('error'));
}
if(statement){
console.log('statement 2');
reject(throw new Error('error'));
}
});
}
Promise.try()示例:
function tryExample(){
return Promise.try(function(){
if(statement){
console.log('statement 1');
throw new Error('error');
}
if(statement){
console.log('statement 2');
throw new Error('error');
}
});
}
在這種情況下,您可以主要使用(具有一個行為差異)。 第一個是標准承諾功能,可以與任何promise庫一起使用。
Promise.try()
是一個由Bluebird庫專門實現的功能,並不是我所知道的任何標准流程的一部分。
使用Promise.try()
的原因是,如果您有一個返回promise的函數,但生成該promise的代碼也可能導致同步異常。 由於該異常不在任何promise處理程序中,因此您可以混合使用錯誤處理。 某些代碼執行路徑可能會導致返回將要解析或拒絕的promise,而其他代碼執行路徑可能會引發異常。 要安全地編寫代碼,您必須同時響應promise並在代碼周圍放置一個try / catch塊,這些代碼變得難以處理。
Promise.try()
只是一種自動捕獲任何異常並將其轉化為拒絕的方法(類似於.then()
處理程序中發生的情況)。
在這兩種情況下, Promise.try()
不會以這種方式使您受益,因為new Promise()
回調已經捕獲異常並將它們變為拒絕,因此在那里已經為您完成了功能。 你可以在這里看到: http : //jsfiddle.net/jfriend00/wLov9844/
Bluebird doc提供了這個示例,它更清楚地顯示了這個好處:
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()
始終返回一個promise,即使該方法內部的代碼同步拋出異常。 這簡化了getUserById()
使用,因為您始終只需響應promise,而不必使用自己的異常處理程序。
如果沒有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.try()
也會自動返回已解決的承諾。 由於第一個示例中的一條路徑無法解析或拒絕,因此這會導致兩個示例產生差異。
他們不一樣。
考慮兩個陳述都是假的情況。 在這種情況下, multiRejectExample()
將永遠不會拒絕或解析返回的promise,而tryExample()
將“通過”並自動解析promise(值為undefined
因為您不返回任何內容)。
展示:
var Promise = require('bluebird');
function test1() {
return Promise.try(function() { });
}
function test2() {
return new Promise(function(resolve, reject) { });
}
test1().then(function() { console.log('resolved #1'); });
test2().then(function() { console.log('resolved #2'); });
這將記錄resolved #1
但未resolved #2
因為承諾永遠不會被實際解決(也不會被拒絕)。
以下是相同的嗎?
不,正如@robertklep已經提到過的,當statement
錯誤時,它們會有不同的結果。 Promise.try
捕獲異常並以函數的返回值解析,而Promise
構造函數只是創建一個新的promise而不關心它何時從不resolve()
d。
我什么時候應該使用哪個?
你應該使用Promise
構造函數iff,並且只有當你正在使用異步回調API時才使用它 。 其他一切,尤其是在涉及其他承諾時 ,基本上都是反模式。
所以不要像你在問題中那樣使用它 。
你通常也不throw
。 您正在編寫一個返回promise的函數(因為它是異步的),它應該總是返回一個promise。 如果要返回因錯誤而被拒絕的承諾,可以使用Promise.reject
顯式創建一個Promise.reject
。 因此,正確的方法是
function multiRejectExample(){
if (statement){
console.log('statement 1');
return Promise.reject(new Error('error'));
}
if (statement){
console.log('statement 2');
return Promise.reject(new Error('error'));
}
return Promise.resolve();
}
當然,這個特定的例子沒有多大意義,因為你的案例都不是異步的,根本就沒有理由使用promises。 只需使用拋出異常的同步函數。 通常情況下,你會有一些return …
最后是一個實際的異步承諾,而不是一個undefined
實現。
現在,如果你有這樣的功能,並且厭倦了反復編寫return Promise.reject
,你可以使用Bluebird特定的Promise.try
和Promise.method
方法作為語法糖 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.