解决js代码中的异步代码导致的数据没有拿到就执行后续代码问题 vue

最近项目中遇到js代码同步异步的问题,解决之后,写一篇博客进行记录。(项目中的前端技术是vue,h5也是同一个道理)
js当中的代码是单线程的会从上到下依次执行。
promise 同步执行(es6特性)
axios请求异步执行
async await 同步执行(es7还是es8新加的特性 不了解的可以自行查阅)

解决前的代码:

runAxios(){//测评跟踪跳转过来的方法(执行技术评测请求方法)
            this.$axios.get('/api/instances/rununsuccess/'+JSON.parse(this.wizard).id).then(res => {
                if(res.status === 200){
                    this.results=res.data
                    this.checkStatus(res.data)
                }else {
                    console.log('error!')
                }
            }).catch(res => {
                if(res.code === 400){
                    this.$message(res.message)
                    this.results=res.data
                    this.checkStatus(res.data)
                }
            })
            return true;
        },
        checkStatus(result){//渲染progress数据
            result.forEach((item,index) => {//遍历给时间轴状态添加数值
                switch(item.message){
                    case '运行成功':
                        this.results[index].percentage=100
                        this.results[index].status='success'
                        break;
                    case '运行中':
                        this.results[index].percentage=50
                        this.results[index].status='warning'
                        break;
                    case '运行失败':
                        this.results[index].percentage=100
                        this.results[index].status='exception'
                        break;
                }
            });
        },
        loadInf(){//正常向导操作流程执行下来的方法(执行技术评测请求方法)
            this.$axios.post('/api/instances/runresult',JSON.parse(sessionStorage.guide)).then(res => {//渲染数据
                if(res.status === 200){
                    this.results=res.data
                    this.checkStatus(res.data)
                }else {
                    console.log('error!')
                }
            }).catch(res => {
                if(res.status === 400){
                    this.$message(res.message)
                    this.results=res.data
                    this.checkStatus(res.data)
                }
            })
            return true;
        },
        run(){//执行技术评测按钮事件
            let loadingInstance = Loading.service({ 
                target:this.$refs.result,
                fullscreen: true,
                text:'正在执行技术评测中...',
                background:'rgba(255,255,255,.8)' 
            });
            let promise=new Promise((resolve,reject) =>{
                resolve('success')
            }).then(res => {
                if(this.wizard){//判断是否vuex有数据,从而判断是否是从实例页面跳过来的页面在刷新
                    if(JSON.parse(this.wizard).status === '未运行'){//实例页面过来之后按钮能点击肯定是未运行
                        return this.runAxios()
                    }
                }else{//正常向导流程下来的执行事件
                    return this.loadInf()
                }
            }).then(res => {
                if(res){
                    loadingInstance.close();
                }
            })
        }

此前执行的代码中,希望run()方法中的第一个then()方法return loadinf()的返回值,然后执行第二个then进行关闭loading加载,实际情况总是会先执行run()方法中的第二个then()方法然后loadinf()内部代码才能执行完毕,导致res总是undefined
修改后的代码:

async runAxios(){//测评跟踪跳转过来的方法(执行技术评测请求方法)
            await this.$axios.get('/api/instances/rununsuccess/'+JSON.parse(this.wizard).id).then(res => {
                if(res.status === 200){
                    this.results=res.data
                    this.checkStatus(res.data)
                }else {
                    console.log('error!')
                }
            }).catch(res => {
                if(res.code === 400){
                    this.$message(res.message)
                    this.results=res.data
                    this.checkStatus(res.data)
                }
            })
            return true;
        },
        checkStatus(result){//渲染progress数据
            result.forEach((item,index) => {//遍历给时间轴状态添加数值
                switch(item.message){
                    case '运行成功':
                        this.results[index].percentage=100
                        this.results[index].status='success'
                        break;
                    case '运行中':
                        this.results[index].percentage=50
                        this.results[index].status='warning'
                        break;
                    case '运行失败':
                        this.results[index].percentage=100
                        this.results[index].status='exception'
                        break;
                }
            });
        },
        async loadInf(){//正常向导操作流程执行下来的方法(执行技术评测请求方法)
            await this.$axios.post('/api/instances/runresult',JSON.parse(sessionStorage.guide)).then(res => {//渲染数据
                if(res.status === 200){
                    this.results=res.data
                    this.checkStatus(res.data)
                }else {
                    console.log('error!')
                }
            }).catch(res => {
                if(res.status === 400){
                    this.$message(res.message)
                    this.results=res.data
                    this.checkStatus(res.data)
                }
            })
            return true;
        },
        run(){//执行技术评测按钮事件
            let loadingInstance = Loading.service({ 
                target:this.$refs.result,
                fullscreen: true,
                text:'正在执行技术评测中...',
                background:'rgba(255,255,255,.8)' 
            });
            let promise=new Promise((resolve,reject) =>{
                resolve('success')
            }).then(res => {
                if(this.wizard){//判断是否vuex有数据,从而判断是否是从实例页面跳过来的页面在刷新
                    if(JSON.parse(this.wizard).status === '未运行'){//实例页面过来之后按钮能点击肯定是未运行
                        return this.runAxios()
                    }
                }else{//正常向导流程下来的执行事件
                    return this.loadInf()
                }
            }).then(res => {
                if(res){
                    loadingInstance.close();
                }
            })
        }

给loadInf()添加async await 将axios修改成同步,将代码从上到下依次执行。
之前的原因是因为axios是异步执行的,而我的需求是需要在他执行完毕之后return一个true再执行最后关闭loading
代码虽然执行到了return这一步但是引文loadInf和runAxios这俩方法里面axios是异步执行的 所以还没等他返回东西,就先执行了第二个then()方法,导致第二个then()方法中的res一直是undefined,解决办法就是让那俩方法变成同步执行,给他加async await,就可以完美解决这个问题。

发布了29 篇原创文章 · 获赞 22 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/weixin_41628411/article/details/100030449
今日推荐