NodeJS await/async使数据检索同步



我知道这个问题已经问了几千次了,但我仍然没有找到答案。我有一个forEach循环,用于遍历用户列表并检索每个用户的特定位置数据。在forEach函数内部,第一次函数调用获取分支,第二次函数调用获取该分支的信息。

问题是forEach循环在从函数返回数据之前没有完成,这会导致各种各样的问题。

下面是我的代码:
//getAllUserData() - this is the function which returns prematurely
const getAllUserData = async () => {
const sequelize = DB.GetDB('mcaintranet');
const userDB = MCAIntranet.initModels(sequelize);
userDB.tblUsers.belongsTo(userDB.tblSMSSent, { foreignKey: 'collector', targetKey: 'user' });
userDB.tblSMSSent.hasMany(userDB.tblUsers);
let users = await userDB.tblUsers.findAll({
attributes: ['collector', 'id'],
include: {
model: userDB.tblSMSSent,
attributes: [[sequelize.fn('COUNT', 'tblSMSSent.id'), 'numMessages']]
},
raw: true,
group: ['collector', 'tblUsers.id'],
})
//return list of all users and texts sent
//UserName, User Province Code, # Messages Sent, user  Number
try {
await users.forEach(async user => {
const branch = await Users.getUserBranch(user);
const province = getKey(branch);
user.province = province;
// console.log("User: ", [user, branch])
//clean up JSON from join results
user.numMessages = user["tblSMSSent.numMessages"];
delete user["tblSMSSent.numMessages"];
})
const obj = { 'users': users };
console.log("DONE: ", obj)
return obj;
}
catch (ex) {
console.log("ERROR: ", ex)
const msg = ex.Message;
return { results: "False", message: "SMS.js 61" + msg }; //is user allowed to use SMS page)
}
}
//getUserBranch() - accessor function to return branch number
const getUserBranch = async (user) => {
// console.log("Branch User: ", user)
let branch = getUserProps(user.collector ? user.collector : user, 'branch');
// console.log(props)
if (!branch) branch = 0;
return branch;
}
//getUserProps - pulls all user properties from database and filters as necessary
const getUserProps = async (user, propName = null) => {
let ret = {};
if (user.collector) user = user.collector;
user = user.trim();
let filter = {
collector: user
}
if (propName) {
filter.propertyName = propName
}
// console.log("Filter: ", filter)
const sequelize = DB.GetDB('MCAIntranet');
const propsDB = MCAIntranet.initModels(sequelize);
//get all values contained for user
let props = await propsDB.tblUserProperties.findAll({
attributes: ['id', 'propertyName', 'propertyValue', 'updated'],
where: filter,
order: [['updated', 'DESC']],
})
// console.log("Props: ", props);
let distinctProps = await propsDB.tblUserProperties.findAll({
attributes: ['propertyName'],
DISTINCT: true,
where: filter,
})
//the SMS Credits item is sometimes added as a second row
//so loop through all potential value rows for user
distinctProps.forEach(dr => {
// console.log(dr);
var name = dr.propertyName.toLowerCase();
// console.log("name: ", name)
try {
//get individual values for each property user possesses
let tmpRows = props.filter(row => row.propertyName.toLowerCase() == name);
// console.log("tmpRows: ", tmpRows)
//get the most recent value
let row = tmpRows[tmpRows.length - 1];
var item = row.propertyName.trim();
var value = row.propertyValue.trim();
//add to returned JSON
ret[item] = value;
} catch (ex) {
console.log("USERS.js 157 " + ex.message);
return ({ error: "USERS.js 158" + ex.Message });
}
})
// console.log("Ret: ", ret)
return ret;
}
//getKey() - returns necessary data about the user province
const getKey = (data) => {
let branch;
try {
branch = data.branch ? data.branch : data;
}
catch (ex) {
console.log(data)
console.log(ex)
}
branch = parseInt(branch);
// console.log(branch)
try {
let acctKey = "";
let province = "";
let abbr = "";
// console.log("Branch: ", branch)
switch (branch) {
case 4: //vancouver
case '4':
abbr = "BC";
acctKey = key["BC"];
province = "British Columbia";
break;
case 7: //Montreal
case '7':
abbr = "QC";
acctKey = key["QC"];
province = "Quebec";
break;
case 9: //Toronto
case '9':
abbr = "ON";
acctKey = key["ON"];
province = "Ontario";
break;
default: //Edmonton
abbr = "AB";
acctKey = key["AB"];
province = "Alberta";
break;
}
return { key: acctKey, province: province, abbr: abbr };
}
catch (ex) {
throw ex;
}
}

在等待和异步的集合中,缺少了一些东西,导致getAllData()函数返回用户名而不返回位置数据。我如何阻止执行,直到我有所有的数据?在我努力解决这个问题的过程中,请忽略我所付出的不必要的等待。

谢谢。

你想要的不是forEach,而是:

await Promise.all(users.map(async (user) => {...}))

map返回每个内部操作的承诺,await-ingPromise.all等待所有这些承诺完成

最新更新