zoukankan      html  css  js  c++  java
  • 使用promise封装一个retry

    今天被问到:使用promise封装一个retry函数,如果一个请求失败,重试几次后也失败就抛出错误

    以下为失败尝试,可以直接跳转到完整案例

    如果您有更好的案例,欢迎分享

    完整案例

    失败经历

    我简单思考了一下,这里可以用递归,写出了如下代码

    function retry (task, count) {
        return new Promise((resolve, reject) => {
            task.then(res => { // 未执行
                resolve(res)
            })
            .catch(() => {
                if (count > 0) {
                    return retry(task, count--) // 死循环
                }
                else {
                    reject('次数用完了')
                }
            })
        })
    }
    

    写了一个测试用例,好家伙,直接崩了。。。
    修改注释的错误后,我又上路了

    function retry (task, count) {
        return new Promise((resolve, reject) => {
            task().then(res => {
                resolve(res)
            })
            .catch(() => {
                if (count > 0) {
                    return retry(task, count-1)
                }
                else {
                    reject('次数用完了')
                }
            })
        })
    }
    

    这次算是能实现失败后重试了,但是,当次数用完后抛出了一个错误,程序不能继续执行了

    可是我明明使用了.catch捕获reject啊,这就令人费解了
    报错嘛,大不了我try、catch一下

    那么try、catch加在哪里呢?我想到使用async、await时的一种场景

    async function run() {
        try {
            await retry(task, 1)
        }
        catch (e) {
            console.log(e)
        }
        console.log('done')
    }
     run() 
    

    我低估了异步的错误,这家伙成精了啊
    于是我开始搜索如何解决promise的错误
    都是清一色的.catch(e => {}),我也是这么写的啊,怎么会没有用呢
    我想问题应该在于我catch到了第一次调用,第一次失败并没有reject,而是递归调用了自身,生成了一个新的promise对象
    于是我换了一个思路

    function retry(task, count) {
        console.log('还有' + count + '次')
        return new Promise((resolve, reject) => {
            task()
                .then(res => {
                    resolve(res)
                })
                .catch(() => {
                    if (count > 0) {
                        retry(task, count - 1)
                    } else {
                        reject('次数用完了')
                    }
                })
        }).catch(e => console.log(e)) // 捕获当前promise的错误
    }
    

    这次确实成功捕获到了错误,但是我没法拿到错误,也没能继续执行下去
    既然确定了是因为重试生成promise对象和之前的没有关联,那么,问题很简单就解决了

    完整案例

    经过几次失败,这个案例应该趋于成功了吧

    function retry(task, count) {
        console.log('还有' + count + '次')
        return new Promise((resolve, reject) => {
            task()
                .then(res => {
                    resolve(res)
                })
                .catch(() => {
                    if (count > 0) {
                        resolve(retry(task, count - 1)) // 这里使用resolve
                    } else {
                        reject('次数用完了')
                    }
                })
        })
    }
    
    无个性不签名
  • 相关阅读:
    【狼】狼的unity3d脚本学习
    [转]关于Unity中文件读取
    【狼】unity3d 安卓播放视频替代视频纹理
    SpringMVC异常处理
    springboot 热启动
    旅游网dao层
    MyBatisPlus快速入门
    旅游网dao层
    MySQL8 修改密码验证插件
    Zookeeper环境搭建
  • 原文地址:https://www.cnblogs.com/qinweijie/p/14168705.html
Copyright © 2011-2022 走看看