简体   繁体   中英

How to break out of the promise chain in the middle

Here is my sample code.

Orchestrator calls the worker with couple of inputs first, upon getting the response, it has to validate whether the response was satisfactory or not.

If satisfactory, just return to the caller.

If not, again, call the same worker or may be different worker with slightly different input and follow the flow.

Here, although, my code calls cb() after the first worker call, it's also going to the second then and errors out "response" is undefined etc..

I could add an extra condition to check whether the 1st response was satisfactory, like need2ndworkercall && validate(response) in 2nd then and get away with it. But wondering what is the right way of dealing with this problem. Appreciate any feedback.

  function orchestrateSomething(input, cb){
    doSomething(input.a, input.b)
      .then(response=>{
        if(validate(response)){
          cb(buildResultObj(response));
        }
        else{
          return doSomething(input.a)
        }
      })
      .then(response=>{
        if(validate(response)){
          cb(buildResultObj(response));
        }
        else{
          cb(null,{});
        }
      })
      .catch(error=>cb(error));
  }

return value from function and .then() . Also cb function should call passed function which returns value or evaluate parameters and return value passed

  function orchestrateSomething(input, cb){
    return doSomething(input.a, input.b)
      .then(response=>{
        if(validate(response)){
          return cb(buildResultObj(response));
        }
        else{
          return doSomething(input.a)
        }
      })
      .then(response=>{
        if(validate(response)){
          return cb(buildResultObj(response));
        }
        else{
          return cb(null,{});
        }
      })
      .catch(error=>cb(error));
  }

  orchestrateSomething(input, cb) // where `cb` calls function or values passed
  .then(function(results) {
    console.log(results)
  })
  .catch(function(err) {
    console.log(err)
  });

It is possible break the promise chain via simple throw . The trick is to handle it properly on the catch call:

doPromise(...)
  .then(...)
  .then(result => {
    if(condition) {
      throw result
    }
    else {
      return doPromise()
    }
  })
  .then(...)
  .catch(result => {
    if(result instanceof Error) {
      // handle error result
    }
    else {
      // handle desired result
    }
  })

Here's the simpliest demo of such approach: http://plnkr.co/edit/H7K5UsZIueUY5LdTZH2S?p=preview

By the way, if you can generalize then processing function, it becomes possible to make a recursive call:

processCB = (result) => {
  if(condition) {
    throw result
  }
  else {
    return doPromise()
  }
}

catchCB = (result) => {
  if(result instanceof Error) {
    // handle error result
  }
  else {
    // handle desired result
  }
}

doProcess = () => doPromise()
  .then(processCB)
  .catch(catchCB)

And here's the demo for the second piece: http://plnkr.co/edit/DF28KgBOHnjopPaQtjPl?p=preview

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