首县,我先说一下我这个虚拟的需求,我从数据库中查找所有用户的信息,包括省市县,但是我存储的时候是以省码、市码、县码code的形式来存储到数据库的,所有我取出来的时候还需要去数据库省市县表中查找对应的name,所有产生了这个问题。
刚开始的思路很直接,很明确,就是找到所有人数据之后,进行循环,插入新属性,返回数据给前端。
//所有 user 用户信息
router.get('/queryAllUserInfo', async function (req, res, next) {
let data = await Db.DBFunPro(`select user_info.uuid,user_info.name,user_info.sex,user_info.tel,user_info.pro,user_info.city,user_info.area,user.username,user.password,user_info.fileUrl from user_info, user where user.uuid = user_info.uuid`)
let forFun = async (item) => {
let prostr = await Db.DBFunPro(`select pro_name from pros where pro_id='${
item.pro}'`)
let citystr = await Db.DBFunPro(`select city_name from cities where city_id='${
item.city}'`)
let areastr = await Db.DBFunPro(`select area_name from areas where area_id='${
item.area}'`)
return prostr[0].pro_name + citystr[0].city_name + areastr[0].area_name
}
data.map(async item=>{
let codeStr = await forFun(item)
item.codeStr = codeStr
console.log(item,'item');
})
res.send(endMassage(data))
});
上面的代码并不能解决问题,并没有将字段codeStr加上,但是在node端能打印到已经加上了,看下面两个图:
这是前端截图,发现并没有codeStr字段,但是:
在node端打印是能获取到值的。发生了异步事件。
分割线==========================================================
分析:
在返回之后,map循环中的forFun才执行完,map循环的参数一个函数,map循环完一次调用多个函数,每一个函数的第一个参数item就是数组的每一项,map只管执行回调函数item=>{},只要这个执行完,就算执行完,并不管你这个函数里面是否是异步,所以,并不能通过async await的形式控制map循环。
当然,我们换一种形式,我们将循环放到函数里面 ,控制函数异步:
//所有 user 用户信息
router.get('/queryAllUserInfo', async function (req, res, next) {
let data = await Db.DBFunPro(`select user_info.uuid,user_info.name,user_info.sex,user_info.tel,user_info.pro,user_info.city,user_info.area,user.username,user.password,user_info.fileUrl from user_info, user where user.uuid = user_info.uuid`)
let forFun = async (item) => {
let prostr = await Db.DBFunPro(`select pro_name from pros where pro_id='${
item.pro}'`)
let citystr = await Db.DBFunPro(`select city_name from cities where city_id='${
item.city}'`)
let areastr = await Db.DBFunPro(`select area_name from areas where area_id='${
item.area}'`)
return prostr[0].pro_name + citystr[0].city_name + areastr[0].area_name
}
let datap = async () => {
//map加不上
data.map(async item => {
let codeStr = await forFun(item)
item.codeStr = codeStr
console.log(item,'item');
})
return data
}
let datap2 = await datap()
res.send(endMassage(datap2))
});
同样的,这也不行,原因和上面一样。
分割线==========================================================
下面我们不适用map来实现一下,我们使用for:
//所有 user 用户信息
router.get('/queryAllUserInfo', async function (req, res, next) {
let data = await Db.DBFunPro(`select user_info.uuid,user_info.name,user_info.sex,user_info.tel,user_info.pro,user_info.city,user_info.area,user.username,user.password,user_info.fileUrl from user_info, user where user.uuid = user_info.uuid`)
let forFun = async (item) => {
let prostr = await Db.DBFunPro(`select pro_name from pros where pro_id='${
item.pro}'`)
let citystr = await Db.DBFunPro(`select city_name from cities where city_id='${
item.city}'`)
let areastr = await Db.DBFunPro(`select area_name from areas where area_id='${
item.area}'`)
return prostr[0].pro_name + citystr[0].city_name + areastr[0].area_name
}
//for可以加上
for (let index = 0; index < data.length; index++) {
let codeStr = await forFun(data[index])
data[index].codeStr = codeStr
console.log(data[index], 'data[index]');
}
res.send(endMassage(data))
});
很直接的完成了我们的需求,这源于for循环的机制流程:
首先判断1这个条件,执行2中的代码块,只有执行将await执行完,在执行3,以此循环。