使用自定义错误处理程序中止多步承诺链

Aborting multiple-step promise chains with custom error handlers

我正在编写一个多步异步序列,每一步都涉及不同的可能错误。如果发生错误,我想中止整个序列。

我正在尝试使用 Promise.then()Promise.catch() 将其表示为线性序列。这是伪代码:

step1()
.catch(errorAtStep1 => handlerErrorAtStep1)
.then(resultOfStep1 => step2(resultOfStep1))
.catch(errorAtStep2 => handlerErrorAtStep2)
.then(resultOfStep2 => step3(resultOfStep2))
...

我知道我需要在每个错误处理程序中抛出 东西 以避免返回到 then(result) 部分。但是,当我抛出时,执行在下一个 catch(error) 块中结束,该块预期会出现与其相应步骤相关的错误,而不是我抛出的其他内容。

我的问题是:有什么简洁的方法可以处理此问题,从而最大限度地减少阅读代码时的注意力分散?

我想出了这个 class:

class AbortChainError extends Error {
  static chain(handler) {
    return function(error) {
      if (error instanceof AbortChainError) throw error
      handler(error)
      throw new AbortChainError()
    }
  }
}

允许 catch() 块被写为:

.catch(AbortChainError.chain(errorAtStep2 => handlerErrorAtStep2))

额外需要在序列末尾写入一个最终的空 catch() 块。

我们可以做得更好吗?

如果你把它放到一个异步函数中,我没有错误处理程序 return 什么,然后你可以执行每个步骤 one-by-one 并查看结果是否存在 - 如果没有,出现错误,你可以 return.

const doStuff = async () => {
  const r1 = await step1().catch(handlerErrorAtStep1);
  if (!r1) return;
  const r2 = await step2(r1).catch(handlerErrorAtStep2);
  if (!r2) return;
  // etc

它不是 DRY,但我认为它是最容易理解的。