2015-08-21 50 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方法为语法糖

相关问题