Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/eclipse/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何走出中间的承诺链_Javascript_Promise_Es6 Promise - Fatal编程技术网

Javascript 如何走出中间的承诺链

Javascript 如何走出中间的承诺链,javascript,promise,es6-promise,Javascript,Promise,Es6 Promise,这是我的示例代码 Orchestrator首先使用两个输入调用worker,在得到响应后,它必须验证响应是否令人满意 如果满意,只需返回给来电者即可 如果不是,再次呼叫同一个工作人员,或者可能是输入略有不同的不同工作人员,并遵循流程 在这里,虽然我的代码在第一次工作调用之后调用cb(),但它也会在第二次调用之后出错,因为“response”未定义等等 我可以添加一个额外的条件来检查第一个响应是否令人满意,比如在第二个响应中需要第二个WorkerCall&&validate(响应),然后就可以了。

这是我的示例代码

Orchestrator首先使用两个输入调用worker,在得到响应后,它必须验证响应是否令人满意

如果满意,只需返回给来电者即可

如果不是,再次呼叫同一个工作人员,或者可能是输入略有不同的不同工作人员,并遵循流程

在这里,虽然我的代码在第一次工作调用之后调用cb(),但它也会在第二次调用之后出错,因为“response”未定义等等

我可以添加一个额外的条件来检查第一个响应是否令人满意,比如在第二个响应中需要第二个WorkerCall&&validate(响应),然后就可以了。但是想知道什么是处理这个问题的正确方法。感谢您的反馈

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

从函数和
返回值。然后()
。此外,
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)
  });

可以通过简单的
抛出
来打破承诺链。诀窍是在
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
    }
  })
下面是这种方法最简单的演示:

顺便说一句,如果您可以泛化
然后
处理函数,则可以进行递归调用:

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)

下面是第二部分的演示:

如果希望有条件地执行链的某些部分,则需要创建分支而不是直链。搜索“promise branch vs.chain”,您会发现许多文章(有些是关于stackoverflow的)对此进行了解释。请参阅