【Vue】解决for循环中无法等待回调的问题
文章目录
前言
项目中有一个需要循环获取多日信息的问题,但在for循环中发送请求没办法让循环等待回调结果接收到后再执行下一步,所以会出现各种各样的问题。
这是在个例中的解决方法,希望能起到抛砖引玉的作用。
一、旧思路
最初的思路是通过()方法等待回调数据都收到后再对数据执行操作,但这样的方式灵活性很差。
然后就想到了async/await的方式,使for循环等待接收到回调结果再进行下一步操作。但这方式好像只能对对象使用,我这边返回的是对象,就没能起到作用。
for (let i = 0; i<7; i++){console.log("for循环"+i)L.supermap.featureService(url).getFeaturesBySQL(sqlParam, (serviceResult) => {// console.log(serviceResult)console.log("回调"+i)})}
结果如下:
可以发现for循环结束后回调结果才姗姗来迟,而且返回顺序不确定,假设我想在i=0的时候给数组新建子项,如果此时先返回的是回调3,那么之后的操作就会报错。
二、新思路
之前寻找解决方案的时候有看到过使用回调替代for循环的方法,但当时脑子没转过来,觉得挺麻烦的就没弄。结果在多次碰壁后又捡起了回调的方法,没想到成功解决了问题。
解决方法示例:
testB(i) {if (i<7){L.supermap.featureService(url).getFeaturesBySQL(sqlParam, (serviceResult) => {console.log("回调"+i)this.testB(i+1)})}else {console.log("回调结束")}},
结果如下:
三、实际案例
原始代码如下:
rainfallScatter() { //x日累计降雨量分布图///获取城市七日间降雨总量let date = this.formatOfDate(this.value1)let rainfall_total = []let rainfall_sum = []for (let i = 0; i<7; i++){let sqlDate = "日期 like '" + this.GTDate(date, i) + "%'" //SQL语句about日期let sqlParam = new SuperMap.GetFeaturesBySQLParameters({queryParameter: {name: "全国省会城市气象数据表@ChinaClimate",attributeFilter: sqlDate},datasetNames: ["ChinaClimate:全国省会城市气象数据表"],toIndex: -1 //返回至多1000条数据(在没有修改IServer文件的前提下)})console.log("for循环"+i)L.supermap.featureService("http://localhost:8090/iserver/services/data-ChinaClimate/rest/data").getFeaturesBySQL(sqlParam, (serviceResult) => {// console.log(serviceResult)if (i == 0){for (let ii = 0; ii < serviceResult.result.featureCount; ii++){rainfall_total[ii] = []}}for (let j = 0; j < serviceResult.result.featureCount; j++){rainfall_total[j].push(parseFloat(serviceResult.result.features.features[j].properties.降雨量MM))}console.log("回调"+i)})}setTimeout(() => {for (let j = 0; j < rainfall_total.length; j++){let sum = 0rainfall_sum[j] = []for (let k = 0; k < rainfall_total[j].length; k++){sum += rainfall_total[j][k]}rainfall_sum[j] = sum}// console.log(rainfall_total)// console.log(rainfall_sum)}, 50)},
修改后代码如下:
testB(i, rainfall_total) {let date = this.formatOfDate(this.value1)if (i<7){let sqlDate = "日期 like '" + this.GTDate(date, i) + "%'" //SQL语句about日期let sqlParam = new SuperMap.GetFeaturesBySQLParameters({queryParameter: {name: "全国省会城市气象数据表@ChinaClimate",attributeFilter: sqlDate},datasetNames: ["ChinaClimate:全国省会城市气象数据表"],toIndex: -1 //返回至多1000条数据(在没有修改IServer文件的前提下)})L.supermap.featureService("http://localhost:8090/iserver/services/data-ChinaClimate/rest/data").getFeaturesBySQL(sqlParam, (serviceResult) => {// console.log(serviceResult)console.log("回调"+i)if (i == 0){for (let ii = 0; ii < serviceResult.result.featureCount; ii++){rainfall_total[ii] = []}}for (let j = 0; j < serviceResult.result.featureCount; j++){rainfall_total[j].push(parseFloat(serviceResult.result.features.features[j].properties.降雨量MM))}this.testB(i+1, rainfall_total)})}else {let rainfall_sum = []for (let j = 0; j < rainfall_total.length; j++){let sum = 0rainfall_sum[j] = []for (let k = 0; k < rainfall_total[j].length; k++){sum += rainfall_total[j][k]}rainfall_sum[j] = sum}// console.log(rainfall_total)// console.log(rainfall_sum)console.log("回调结束。")}},},
testB调用时给上一个初始值即可,例如:
testB(0, [])