如何打破中间的承诺链

时间:2017-04-17 03:31:38

标签: javascript promise es6-promise

这是我的示例代码。

Orchestrator首先通过几个输入调用工作者,在得到响应后,它必须验证响应是否令人满意。

如果满意,只需返回来电。

如果没有,再次呼叫同一个工作人员,或者可能是输入稍有不同的不同工人,并按照流程进行。

虽然,我的代码在第一次工作呼叫之后调用了cb(),然后它也会转到第二个,然后出现错误"响应"未定义等。

我可以添加一个额外的条件来检查第一个响应是否令人满意,例如need2ndworkercall&&在第二个验证(响应)然后逃脱它。但是想知道处理这个问题的正确方法是什么。感谢任何反馈。

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

2 个答案:

答案 0 :(得分:0)

来自函数和return

.then()值。另外cb函数应调用传递的函数,该函数返回值或评估参数并返回传递的值

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

答案 1 :(得分:0)

可以通过简单的throw打破承诺链。诀窍是在catch调用上正确处理它:

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

以下是此类方法的最简单演示:http://plnkr.co/edit/H7K5UsZIueUY5LdTZH2S?p=preview

顺便说一下,如果你可以推广then处理函数,就可以进行递归调用:

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)

这是第二部分的演示:http://plnkr.co/edit/DF28KgBOHnjopPaQtjPl?p=preview