条件承诺链

Conditional promise chain

我正在寻找一些将一些承诺链接在一起的代码。我有一个条件,基于一个承诺的结果,我要么调用下一个 returns 承诺的函数并继续链接另外几个函数,要么什么也不做(有效地结束承诺链)。

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

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

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

您的第一种方法似乎不错,为了避免嵌套,您可以 return promise 并像这样为嵌套部分添加一个额外的 then 块

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

如果你不喜欢在第三种方法中抛出不必要的错误,你可以使用 async/await 来获得更多控制并摆脱函数 scope/nesting 问题,这也被推荐用于由于更好的错误堆栈跟踪,新的 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);
}