V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
baskice
V2EX  ›  问与答

如何写一个 JavaScript 通用的重试 function?

  •  
  •   baskice · 2017-10-06 06:05:37 +08:00 · 4127 次点击
    这是一个创建于 2638 天前的主题,其中的信息可能已经有所发展或是发生改变。
    我再写一个简单的虚拟货币暴跌提示。但是交易所的 api 经常性会返回各种稀奇古怪内容或者干脆超时。

    我希望能写一个通用的重试 function 把价格请求部分包起来。这样出错的话,反复尝试直到设置的上限停止。

    function errorReTry(status) {
    var retries = 10;
    while (retries-- > 0 && !status) { //这样写真的有用吗?
    Sleep(1000);
    }
    return status;
    }
    14 条回复    2017-10-08 01:49:30 +08:00
    laxenade
        1
    laxenade  
       2017-10-06 06:52:47 +08:00
    你可以试试 RxJS 的 RetryWhen。应该还有其他方法,优雅的暂时只想到了这个。
    baskice
        2
    baskice  
    OP
       2017-10-06 07:13:37 +08:00
    @laxenade 简单包起来即可……不需要这么复杂的……这重试比我代码都长了 https://github.com/Reactive-Extensions/RxJS
    xrr2016
        3
    xrr2016  
       2017-10-06 07:31:57 +08:00 via Android
    干嘛不用 Promise.all
    vghdjgh
        4
    vghdjgh  
       2017-10-06 08:28:38 +08:00
    虽然是 reconnection 库,也可以用来做 retry
    https://github.com/plantain-00/reconnection#usage
    rekulas
        5
    rekulas  
       2017-10-06 08:32:12 +08:00
    可以用 coinmarketcap 的数据吧,已经帮你整合好了
    wxt2005
        6
    wxt2005  
       2017-10-06 08:47:13 +08:00   ❤️ 1
    http://jsbin.com/teluve/edit?js,console

    写得不太完善,LZ 看看能不能凑合用用。
    k9982874
        7
    k9982874  
       2017-10-06 08:53:57 +08:00
    为啥不直接用 setTimeout ?
    NemoAlex
        8
    NemoAlex  
       2017-10-06 09:30:05 +08:00 via iPhone
    在解决这个问题之前,你需要先弄清楚几个事情:
    是前端用还是 Node 用?使用哪个 HTTP Client 库?
    前端用的话,用户的浏览器会不会不支持 Promise ?如果存在的话,是不用 Promise,还是加一个 Polyfill ?
    从你写的东西来看,对于 JS 的基础理解还不够,建议先完善下基础。

    我比较推荐的方式是采用 Promise + axios。至于 retry,有个 axios retry 的插件,不过不能很好地处理超时的情况。如果这方面是必须的话,建议自己简单写实现一下。
    iamppz
        9
    iamppz  
       2017-10-06 09:42:35 +08:00 via iPhone
    ES6 的 promise 几行代码的事情
    cloud107202
        10
    cloud107202  
       2017-10-06 10:55:04 +08:00   ❤️ 2
    ```
    function timeout(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
    }


    // e.g.
    async function waiting_until_succeed(retry_interval = 2000) {
    try {
    const result = await api_client.getXXByXX();
    } catch (err) {
    logger.info(` ${err.message}`);
    await timeout(retry_interval);
    return waiting_until_succeed();
    }
    }

    ```
    azh7138m
        11
    azh7138m  
       2017-10-06 14:16:53 +08:00 via Android
    @cloud107202 race 不更好吗。。。对 chrome 更友好
    cloud107202
        12
    cloud107202  
       2017-10-06 18:38:26 +08:00
    @azh7138m 是 Promise.race() 么
    azh7138m
        13
    azh7138m  
       2017-10-06 18:44:01 +08:00 via Android
    @cloud107202 嗯,稍微封装下就有超时重试了
    baskice
        14
    baskice  
    OP
       2017-10-08 01:49:30 +08:00
    Promise 可行,谢谢
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5741 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 03:06 · PVG 11:06 · LAX 19:06 · JFK 22:06
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.