最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Try and catch around promise - Stack Overflow

programmeradmin1浏览0评论

I need to write a function that returns a promise, where first I call a synchronous function A() which returns some result. Then return a function B(result) where B is a promise which takes in the result of A(). If either function fails I want the same error function C(error) to get called where C is a promise. What is the best way of writing this. This is what I have but think there is obvious way I am missing

function() {
    try {
        var result = A();
        return B(result)
            .catch(function(error) {
                return C(error);
            });
     }
     catch(error) {
         return C(error);
     }
}

It seems wrong bining synchronous try and catch with a promise .catch and also wrong there are two different places I need to call C(error).

A() throws an error rather than returning an error code.

I need to write a function that returns a promise, where first I call a synchronous function A() which returns some result. Then return a function B(result) where B is a promise which takes in the result of A(). If either function fails I want the same error function C(error) to get called where C is a promise. What is the best way of writing this. This is what I have but think there is obvious way I am missing

function() {
    try {
        var result = A();
        return B(result)
            .catch(function(error) {
                return C(error);
            });
     }
     catch(error) {
         return C(error);
     }
}

It seems wrong bining synchronous try and catch with a promise .catch and also wrong there are two different places I need to call C(error).

A() throws an error rather than returning an error code.

Share Improve this question edited Jun 23, 2016 at 14:59 user2802557 asked Jun 23, 2016 at 13:15 user2802557user2802557 8151 gold badge10 silver badges22 bronze badges 4
  • You know the difference between try/catch and the catch function of Promise? Are you actually trying to handle exceptions/errors as try/catch does, or are you trying to do somthing if a promise resolves/rejects as catch and then functions of Promise do? – AUsr19532 Commented Jun 23, 2016 at 13:21
  • When you say either function fails, what does that mean for A()? Does A return an error code that would indicate failure? Does it throw an exception? What type of failure are you trying to detect? Please be more specific so we can offer the best answer. Also, you say you always ways C(error) called, but C is a promise. That statement does make sense. You don't execute a promise like that. What exactly do you mean by that. Do you mean that C is a function you want called if there's an error? – jfriend00 Commented Jun 23, 2016 at 13:51
  • I meant C is a function that returns a promise. – user2802557 Commented Jun 23, 2016 at 14:48
  • A() throws an error rather than returning an error code – user2802557 Commented Jun 23, 2016 at 14:48
Add a ment  | 

3 Answers 3

Reset to default 2

You don't say exactly how A() fails. It could either throw or it could return an error result. I'll show a scheme for both. The key to a mix of sync and async is to always return a promise. This will give you a consistent interface for teh caller no matter how the function succeeds or fails.

If you are only worried about A() throwing an exception and it doesn't return an error code, then you can do this:

function someFunction() {
    try {
        var result = A();
        return B(result);
     } catch(err) {
         return Promise.reject(err);
     }
}

someFunction().then(function(result) {
    // code here to process the final result
}).catch(C);

If you also have the case where A() can return an error code, then you can do this:

function someFunction() {
    try {
        var result = A();
        // check for error value
        if (result < 0) {
            throw result;
        }
        return B(result);
     } catch(err) {
         return Promise.resolve(err);
     }
}

Note that both of these patterns avoid creating an extra promise if it isn't needed. They only create the extra promise when returning an error that occurred synchronously.


The Bluebird promise library has a helper function for this particular circumstance called Promise.method. The utility of Promise.method() is that it automatically wraps your function in a try/catch handler and if there are any synchronous exceptions thrown, it automatically turns them into returning a rejected promise. You could use it like this:

var someFunction = Promise.method(function() {
    var result = A();
    // check for error condition
    if (result < 0) {
        throw result;
    }
    return B(result);
});

someFunction().then(function(result) {
    // code here to process the final result
}).catch(C);

I'm assuming that both A and B can throw errors here. Using the standard API it could look like this:

function() {
  return new Promise((resolve, reject) => {
    try {
      resolve(A());
    } catch (error) {
      reject(error);
    }
  })
  .then(B)
  .catch(C);  
}

This will return a promise that's either resolved with the output of B or the output of C, if that provides a fallback. You can also consider handling any errors outside of this function if that makes sense for your use case.

When using Bluebird this should also be possible:

function() {
  return Promise.method(A)().then(B).catch(C)
}

I think a good way to do this would be to still use promises for the synchronous function. It keeps it consistent within a function, especially if you want something to respond to the success like a pseudo-promise. But the key is that you'd use an immediately resolved promise. Take a look at this blog post on ES6 Promises.

// an immediately resolved promise
var a = Promise.resolve(A());

assuming you've already created the promise and defined C like so:

var B = new Promise(function(resolve, reject) {  
   if (a) {
      resolve('success');  // fulfilled successfully
   }
   else {
      C('rejected');  // error, rejected
   }
})
.then((result) => {console.log('made it!');})
.catch((result) => {C('rejected');});

var C = (err)=>{console.log('error: ' + err); return err;}

this code should do what you want:

a.then((result) => B(result));

^ this last line is the most important, since it uses the output for A to call B

发布评论

评论列表(0)

  1. 暂无评论