【问题标题】:Retrying a failed async/promise function?重试失败的异步/承诺功能?
【发布时间】:2019-05-27 16:00:12
【问题描述】:

我有这个异步块:

test().then(function(result){
    // Success: Do something.
    doSomething();
}).catch(function(error){
    // Error: Handle the error, retry!
    // How to re-run this whole block?
});

我可以跟踪successfailed 结果。但是,如果我们失败了,是否可以重试整个test().then().catch() 链?并继续重试直到条件解决?

【问题讨论】:

  • 把它放在一个函数中。调用它。
  • 请注意,您应该限制重试的频率,甚至是退避延迟,这样您就不会陷入无限循环并可能会耗尽 test 或 @ 中的任何资源987654327@ 失败。
  • 喜欢,使用setTimeout()?

标签: javascript node.js asynchronous promise


【解决方案1】:

如果您可以切换到async/await 语法,则可以使用while 循环:

let keepTrying;

do {
    try {
        await test();
        keepTrying = false;
    } catch {
        keepTrying = true;
    }
} while (keepTrying)

doSomething();

然后您可以将重试逻辑抽象为它自己的函数以供重用。

【讨论】:

    【解决方案2】:

    假设这一切都是关于向一些错误/膨胀的第 3 方 API 重新发送请求

    如果是生产问题而不是教育问题,我建议搜索可以自行实施的第 3 方库。

    axios 有很好的axios-retry

    为什么?假设您可能认为 API say 返回 502 只有一种情况。但实际上还有更多情况,最好记住:

    1. 不同的特定错误原因,例如一旦出现网络或 DNS 查找错误,可能无需重复请求
    2. 重试次数限制
    3. 延迟增加
    4. 别的东西

    自己编写这样的逻辑实在是大材小用。并且尝试使用最简单的解决方案可能会在您意想不到的时候打击您。

    PS 还作为奖励,您可以使用单个 sn-p 配置对某些特定 API 的所有请求,就像它适用于 axios' 自定义实例(我相信应该有其他插件用于替代库)

    【讨论】:

      【解决方案3】:

      如果输入catch 块,您可以将整个内容放入递归调用自身的函数中:

      function tryTest() {
        return test().then(function(result) {
          // Success: Do something.
          doSomething();
        }).catch(function(error) {
          // error handling
      
          // make sure to return here,
          // so that the initial call of tryTest can know when the whole operation was successful
          return tryTest();
        });
      }
      
      
      tryTest()
        .then(() => {
          console.log('Finished successfully');
        });
      

      如果您的doSomething 可以接受result 参数,并且如果tryTest 不接受任何参数,您可以将上述简化为:

      function tryTest() {
        return test()
          .then(doSomething)
          .catch(tryTest);
      }
      
      
      tryTest()
        .then(() => {
          console.log('Finished successfully');
        });
      

      【讨论】:

        【解决方案4】:

        你可以把它放在一个函数中。

        function dbug() {
        
        test().then(function(result){
            // Success: Do something.
            doSomething();
        }).catch(function(error){
            // Error: Handle the error, retry!
            dbug()
        });
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-12-31
          • 2020-10-08
          • 2017-03-26
          • 2017-07-29
          • 2015-08-12
          • 2016-10-25
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多