2015-08-21 105 views
5

什麼時候應該使用哪個?以下是否一樣?Bluebird.JS Promise:new Promise(function(resolve,reject){})vs Promise.try(function(){})

新無極()例如:

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'); 
    } 
    }); 
} 
+0

鬆散相關:[Promise.reject vs throw error](http://stackoverflow.com/q/28703241/1048572)。你不應該使用'new Promise'構造函數,除非你真的在做一些異步的事情。這裏的正確方法是'返回Promise.reject(...)'(或使用'Promise.try' /'Promise.method')。 – Bergi

回答

8

您可以用得最多無論是在這種情況下(有一個行爲差)。第一個是標準的承諾功能,可以與任何承諾庫一起工作。

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()會是什麼自動返回已解決的承諾,如果您沒有自己回覆承諾。由於通過第一個示例的一條路徑不能解決或拒絕,因此這會導致您的兩個示例有所不同。

3

它們是不一樣的。

考慮兩種說法都是錯誤的情況。在這種情況下,multiRejectExample()決不會拒絕解決退回的承諾,而tryExample()將「落空」並自動解決承諾(值爲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由於前景從來沒有真正得到解決(也不拒絕)。

3

下面是否一樣?

不能。正如@robertklep已經提到的那樣,當statement爲假時,他們確實有不同的結果。 Promise.try捕獲異常,並用函數的返回值解決,而構造函數Promise只是創建一個新的承諾,並不在乎它何時不是resolve() d。

什麼時候應該使用哪個?

您應該使用Promise構造IFF和真的只有,你是promisifying an asynchronous callback API。其他一切,特別是when involving other promises,基本上都是反模式。
所以不要使用它就像你在你的問題。

您通常也不會throw。你正在編寫一個返回promise的函數(因爲它是異步的),它應該總是返回一個promise。如果您想返回拒絕並帶有錯誤的承諾,則可以使用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(); 
} 

當然,這個特殊的例子並沒有多大意義,因爲沒有你的情況下是異步的,而且也沒有理由使用承諾在所有。只需使用一個拋出異常的同步函數。通常情況下,最終你會得到一些return …,這實際上是異步承諾,而不是undefined。現在

,如果你有這樣的功能,並且是厭倦了重複寫入return Promise.reject,您可以使用藍鳥特定Promise.tryPromise.method方法爲語法糖

相關問題