有条件的承诺链

时间:2019-07-26 12:36:09

标签: node.js promise bluebird

我正在寻找编写一些将某些承诺链接在一起的代码。我有一个条件,根据一个promise的结果,我要么调用返回一个promise的下一个函数,然后继续链接另外几个函数,要么不执行任何操作(有效地结束promise链)。

我有以下三种可能的解决方案,不过我觉得它们都有些混乱。

这是我的第一种方法,在这里我不喜欢嵌套的诺言。

initalAsyncCall()
  .then((shouldContinue) => {
    if (shouldContinue) {
      return nextStep()
        .then(() => anotherStep())
    }
  })
  .catch((error) => {
    handleError(error);
  })

这是我的第二个。这个似乎更长一些,而且可能更难阅读

const shouldContinuePromise = initialAsyncCall();
const nextStepPromise = shouldContinuePromise.then((shouldContinue) => {
  if (shouldContinue) return nextStep();
});
Promise.all([shouldContinuePromise, nextStepPromise])
  .spread((shouldContinue) => {
    if (shouldContinue) return anotherStep();
  })
  .catch((error) => {
    handleError(error);
  });

最后这是我的最后一种方法。我不喜欢这里的是当我不是真正的错误时抛出错误。

initalAsyncCall()
  .then((shouldContinue) => {
    if (!shouldContinue) throw new HaltException()
    return nextStep();
  })
  .then(() => anotherStep())
  .catch(HaltException, (ex) => {
    // do nothing... maybe some logging
  })
  .catch((error) => {
    handleError(error);
  })

1 个答案:

答案 0 :(得分:0)

您的第一种方法似乎很好,为避免嵌套,您可以返回promise,并为嵌套部分添加一个额外的然后块

initalAsyncCall()
  .then((shouldContinue) => {
    if (shouldContinue) {
      return nextStep()
    } else {
      throw Error('skip next step')
    }
  })
  .then(() => anotherStep())
  .catch((error) => {
    handleError(error);
  })

如果您不喜欢在第三种方法中引发不必要的错误,则可以使用async / await进行更多控制并摆脱函数作用域/嵌套问题,由于以下原因,建议在新的nodejs版本中使用它:更好的错误堆栈跟踪。

try {
    const shouldContinue = await initalAsyncCall()
    if (shouldContinue) {
      await nextStep()
      await anotherStep()
// or await Promise.all([nextStep(), anotherStep()]) if they're not dependent
    }
}
catch (error) {
  handleError(error);
}