打破 .finally() 链

Break a .finally() chain

我有以下链。

  return axios
        .get(actionUrl, {
            params: {
                action: 'action3'
            },
        })
        .finally(() => axios.get(actionUrl, {
            params: {
                action: 'action3'
            },
        }))
        .finally(() => axios.get(actionUrl, {
            params: {
                action: 'action6'
            },
        }))
        .finally(() => axios.get(actionUrl, {
            params: {
                action: 'action1'
            },
        }))

即使前一个失败,我也必须按顺序调用不同的端点。但是,如果端点超时,我想断开链条。如果不使用 .then.catch 并在其中重复相同的代码,是否可以实现?

谢谢。

你熟悉async/await吗?通常你不应该像这样链接 finally,创建递归函数总是更好,例如:

const fetchSomething = async () => {
   try { 
     const result = await axios.get();

     if (...when fetching should stop...) {
       return result;
     }

     return fetchSomething();
   } catch(error) {
     return fetchSomething();
   }
}

但是对于递归函数,创建一些终止开关以防止永远执行它是非常重要的 - 例如设置某种超时,1 分钟左右,如果超过此限制则停止执行。 使用 generatorsyield 可能会更容易,但我从未使用过此解决方案

finally函数就是为了确保即使出现异常,里面的函数也能运行。您只需使用一个 finally 就可以获得您想要的行为:

axios.get()
  .then(() => doStuffOnSuccess())
  .finally(() => {
    axios.get().then(() => doFinallyStuff1())
       .then(() => doFinallyStuff2())
       .then(() => doFinallyStuff3())
       .catch(e => console.error("Finally had trouble",e));
  });

这样,如果 finally 函数中的任何内容超时或失败,它就会断开链。通过最后一次捕获,您将避免它在链条中进一步向上抛出。

这假定您正在正确使用 finally,并且即使有错误,其中的所有内容都应始终在之前的调用完成后执行。

这可以通过 thencatch 实现。如果您不想在出现错误时回调到 运行,则不应使用 finally

I have to sequentially call different endpoints in order even if the previous one fails. However in case an endpoint timeouts I want to break the chain

所以你想在前一个失败时调用它们(超时),你想要做的就是忽略非超时错误。这就是 catch 的用途:

function callEndpoint(action) {
  return axios.get(actionUrl, { params: { action } }).catch(err => {
    if (isTimeout(err))
      throw err
    else
      ; // ignore the error, return undefined
  })
}

然后将它们链接起来:

callEndpoint('action3').then(() => callEndpoint('action6')).then(() => callEndpoint('action3'))