最近在完成一个ERP项目,在采购订单的新增模块,实现一个全选功能,在全选过程中每勾选一个都需要一个函数使用axios去后台请求一次数据,然后渲染到页面。但是循环完成后,页面并没有正确地显示数据,究其原因,在该函数中axios去获取数据是一个异步请求,但是,循环是不断执行的,每次循环axios获取数据还没有完成,就要再一次调用该方法,数据并没有请求成功,而循环已经结束。因此,这样的方法是不能实现我们的目标。所以我们要将axios请求设为同步请求,在jQuery中ajax获取数据有一个特定的参数可以配置该请求是否同步。
我们先说一下jQuery如何实现同步请求。
最常用的是jquery的ajax方法:

$.ajax({
url: "XXX",//请求路径
data: { param1: jsonObj1, params2: str2... },
type: "POST",//GET
//dataType: "JSON",//需要返回JSON对象(如果Ajax返回的是手动拼接的JSON字符串,需要Key,Value都有引号)
success: function(resp) {
//处理 resp.responseText;
},
error: function(a, b, c) {
//a,b,c三个参数,具体请参考JQuery API
}
})

设置为同步请求之后:

$.ajax({
url: "XXX",//请求路径
async: false,//关键是这个参数 是否异步请求=>false:使用同步请求
data: { param1: jsonObj1, params2: str2... },
type: "POST",//GET
//dataType: "JSON",//需要返回JSON对象(如果Ajax返回的是手动拼接的JSON字符串,需要Key,Value都有引号)
success: function(resp) {
//处理 resp.responseText;
},
error: function(a, b, c) {
//a,b,c三个参数,具体请参考JQuery API
}
})

将 async设置为false,,即使用ajax的同步请求。
但是我现在做的项目是基于vue+element-ui构建的项目,在vue中,可以使用ES7的异步特性async / await来实现axios进行同步请求。

getInfoFn: async function(){
var that = this;
await that.$api.scheduleApi.queryScheduleInfoFn(
{caseNo: that.basicInfo.caseNo}).then(function (response) {
if(response.data.code == '200') {
var result = response.data.result;
}
});
},

// 调用getInfoFn()也需要修饰为异步
changeConfigFn: async function(config){

await this.getInfoFn();

// 执行其它操作

}

同步问题解决后,在该项目中我又碰到了一个踩坑点,在循环数组时,我使用了forEach方法,出现了报错。我的代码类似于下面这样子:

function test() {
let arr = [3, 2, 1]
arr.forEach(async item => {
const res = await fetch(item)
console.log(res)
})
console.log('end')
}

function fetch(x) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(x)
}, 500 * x)
})
}

test()

在网上搜索后才发现,forEach 只支持同步代码。forEach 只是简单的执行了下回调函数而已,并不会去处理异步的情况。并且你在 callback 中即使使用 break 也并不能结束遍历。在循环中使用async await,要使用for…of 或者 for 循环, while循环。
我把forEach循环换成for循环以后,问题就迎刃而解了!