记录开发过程中遇到的js同步/异步相关问题

133 阅读1分钟

业务需求及问题现象描述

将后端返回的所有label-value(json数组对象)将其转为map对象并根据后端返回的value值去map中匹配label值时,在页面刷新后会发现拿到存储起来的data值为空,导致值为空 调用了后端的接口 并且后端返回了数据过来,但在vue中使用this.xxx拿到的值为空数组

问题现象代码及截图

jsonStrToMap(jsonObj) {

console.log(jsonObj) // 如截图2
const map = new Map()
for (const v in Object.keys(jsonObj)) {
    for(const k in jsonObj[v]) {
        map.set(k, jsonObj[v][k])
    }
 }
    return map
},
getlist1() {
    apiList1(params).then((res) => {
    this.list1 = res.data
    console.log(res) // 如截图1
    })
},
getlist2() {
    apiList2(params).then((res) => {
    this.list2 = res.data
    console.log(res)// 如截图1
    })
},
setLabelData() {
    apiLabelData(params).then((res) => {
        var listMap1 = this.jsonToMap(this.list1)
        var listMap2 = this.jsonToMap(this.list2)
        console.log(listMap1)// 如截图3
        console.log(listMap2)// 如截图3
    })
}

Screenshot 2023-01-23 at 00.26.15.png

image.png

Screenshot 2023-01-22 at 23.56.58.png

问题类型

此问题其实为异步代码时序问题,在使用json转map的方法时调用接口时还没有拿到promise异步接口返回过来的值 该变量实际为初始声明的空数组 就已经调用该方法了

解决方案

将两个调用接口的异步方法分别使用一层promise包裹住 再在调用转map方法获取map中的值时在其外层使用promis.all 等等两个异步请求完毕后拿到的this.xxx值不为空时再 调用json转map方法 此时从map数据结构中获取到的值不管怎么刷新页面都是不为空的

解决方案代码

主要利用Promise.all 方法, 详见附上的MDN链接


getlist1() {
    return new Promise((resolve, reject) => {  
            apiList1(params).then((res) => { 
              resolve(res);  
            }).catch(e =>{  
              reject(e)  
            })  
     });
},
getlist2() {
    return new Promise((resolve, reject) => {  
            apiList2(params).then((res) => { 
              resolve(res);  
            }).catch(e =>{  
              reject(e)  
            })  
     });
},
setLabelData() {
    apiLabelData(params).then((res) => {
        Promise.all([ this.getlist1(), getlist2() ]).then(res => {  
          // 当this.getlist1(), getlist2()二个函数成功之后才会打印 res  
            console.log(res);  
        })
    })
}