Bluebird.JS承诺:新Promise(函数(解析,拒绝){})vs Promise.try(function(){})

esa*_*z91 5 javascript promise bluebird

我什么时候应该使用哪个?以下是相同的吗?

新的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')); 
   }
  });
}
Run Code Online (Sandbox Code Playgroud)

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'); 
   }
  });
}
Run Code Online (Sandbox Code Playgroud)

jfr*_*d00 8

在这种情况下,您可以主要使用(具有一个行为差异).第一个是标准承诺功能,可以与任何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);
Run Code Online (Sandbox Code Playgroud)

Promise.try()这里的使用确保getUserById()始终返回一个promise,即使该方法中的代码同步抛出异常.这简化了使用,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);
Run Code Online (Sandbox Code Playgroud)

或者,您可以像这样编码:

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);
}
Run Code Online (Sandbox Code Playgroud)

据推测,你可以看到Promise.try()在某些情况下如何简化事情.


仅供参考,在您的第一个示例中,您使用的语法无效.你可以这样做:

reject(throw new Error('error')); 
Run Code Online (Sandbox Code Playgroud)

我假设你的意思是这样的:

reject(new Error('error')); 
Run Code Online (Sandbox Code Playgroud)

虽然我不认为这确实是你所询问的,但Promise.try()如果你自己不回复承诺,也会自动返回已解决的承诺.由于第一个示例中的一条路径无法解析或拒绝,因此这会导致两个示例产生差异.