【问题标题】:Break a .finally() chain打破 .finally() 链
【发布时间】:2020-08-21 03:55:56
【问题描述】:

我有以下链。

  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 并在其中重复相同的代码,是否可以实现?

谢谢。

【问题讨论】:

  • 没有。这正是您应该使用thencatch 的目的。为什么要使用finally
  • 顺便说一句,您已经 正在 在所有行中重复相同的代码。您能否发布您的真实代码,以便我们就如何重构它提出建议?
  • 它们是相同的调用,具有不同的查询参数,必须按顺序进行。

标签: javascript promise finally


【解决方案1】:

这可以通过thencatch 实现。如果您不希望回调在发生错误时运行,则不应使用finally

即使前一个失败,我也必须按顺序调用不同的端点。但是,如果端点超时,我想打破链条

所以你想在前一个失败(超时)时调用它们,你要做的就是忽略非超时错误。这就是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'))

【讨论】:

    【解决方案2】:

    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,并且其中的所有内容都应该在之前的调用完成后执行,即使出现错误也是如此。

    【讨论】:

      【解决方案3】:

      你熟悉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 可能会更容易,但我从未使用过这个解决方案

      【讨论】:

        猜你喜欢
        • 2020-02-23
        • 2022-01-10
        • 2017-11-23
        • 1970-01-01
        • 2016-03-27
        • 1970-01-01
        • 1970-01-01
        • 2017-12-07
        相关资源
        最近更新 更多