Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
360 views
in Technique[技术] by (71.8m points)

javascript - Bluebird.JS Promise: new Promise(function (resolve, reject){}) vs Promise.try(function(){})

When should I use which? Are the following the same?

new Promise() example:

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() example:

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'); 
   }
  });
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You can use mostly either in this case (with one behavior difference). The first is standard promise functionality and will work with any promise library.

Promise.try() is a feature specifically implemented by the Bluebird library and is not part of any standards process that I am aware of.

The reason to use Promise.try() is if you have a function that returns a promise, but the code that generates that promise might also cause a synchronous exception. Since that exception is not inside of any promise handler, you'd have a mix of error handling. Some code execution paths might cause a promise to be returned that would resolve or reject and other code execution paths might throw an exception. To code this safely, you'd have to both respond to the promise and put a try/catch block around the code which gets unwieldy.

Promise.try() is simply a means of automatically catching any exceptions and turning them into a rejection (similar to what happens in .then() handlers).

In your two cases, Promise.try() does not benefit you in that way because the new Promise() callback already catches exceptions and turns them into rejections so that functionality is already being done for you there. You can see that demonstrated here: http://jsfiddle.net/jfriend00/wLov9844/

The Bluebird doc offers this example which shows the benefit more clearly:

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);

The use of Promise.try() here makes sure that getUserById() will always return a promise, even if the code inside of that method throws an exception synchronously. This simplifies use of getUserById() since you can always just respond to the promise and don't have to use your own exception handler around it.

Without Promise.try(), you could code the same thing yourself like this (to catch all possible synchronous exceptions inside the function):

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);

Or, you could code it like this:

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);
}

Presumably, you can see how Promise.try() can simplify things in some circumstances.


FYI, in your first example, you are using invalid syntax. You can do this:

reject(throw new Error('error')); 

I'm assuming what you meant was this:

reject(new Error('error')); 

Though I don't think this is really what you were asking about, Promise.try() will also automatically return a resolved promise if you don't return a promise yourself. Since one path through your first example doesn't resolve or reject, this will cause a difference in your two examples.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...