简体   繁体   中英

Multiple promises in Node with error handling

How can I avoid nesting-hell with a chain of service calls in Node.js, where I'd like to throw a given error and exit the entire chain in certain instances? Here's an example of the chain:

  1. Load Mongoose object.
  2. If load fails, res.send(404) ; if load succeeds, go to the next then() .
  3. Call 3rd party API to get some data.
  4. If API call fails, send proper response (say the proper status code is 500 just for the sake of this problem)
  5. If API call succeeds, render the page.

     SomeMongooseModel.findOne({id:123}).exec() .then(function(response) { // If group is empty, would like to res.send(404) and resolve the // promise immediately. }) .then(function(response) { // Hit 3rd party API to retrieve data. If there's an issue, return // response code of 500 and resolve promise immediately. // Assuming the API call was a success, build out an object and render // the page like so: res.render('some.template', {data: some_data}); }); 

I think this is a decent example of what I'm trying to achieve, but what if we had even more async calls to handle? How can we exit the chain immediately? I've done a bit of searching and I know that I have a lot more to learn, but I'm not finding the ability to simply exit the chains immediately.

When faced with this I normally separate everything into functions, which I then pass a reference into the promise. With good names it also benefits the reading:

function resolveNotFoundIfGroupEmptyOrForwardResponse( response ) { res.send(404) }
function hit3rdPartyApiBasedOnResponse( response ) { 
// throw exception if there is an issue. next step will run the failure state
}    
function render500() { ... }
function renderTemplateWithData( some_data ) { 
   res.render('some.template', {data: some_data});
}

SomeMongooseModel.findOne({id:123}).exec()
    .then( resolveNotFoundIfGroupEmptyOrForwardResponse )
    .then( hit3rdPartyApiBasedOnResponse )
    .then( renderTemplateWithData, render500 )
    .done();

If the function requires an input param that is not comming from the promise chain, then I normally do a function that returns a function.

function doStuffWithParamsCommingFromTwoSides( main_input ) {
   return function( promise_input ) {
         ...
   }
}

then( doStuffWithParamsCommingFromTwoSides( "foobar" ) )

Following Promises/A+ specification, the then steps look like this:

promise.then(onFulfilled, onRejected, onProgress)

Whenever an exception is thrown the next step will run the onRejected . Eventually bubbling up to the done which can also be used to catch the exception bubble.

promise.done(onFulfilled, onRejected, onProgress)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM