node.js - 如何快速执行嵌套 for 循环中编写的等待函数
问题描述
也许我的问题标题是错误的。但我在解释身体的一切。我的问题是我正在为学生详细信息打一个 API。这给了多个学生记录。
响应示例
{
"TotalRecords": "372",
"StudentName": "John Carter",
"StudentImage": "",
"AnotherKey": "Another Value",
"AnotherKey1": "Another Value1",
"ClassDetail": [
{"class":"5","rollnumber":"123"},
{"class":"6","rollnumber":"456"},
{"class":"7","rollnumber":"678"}
],
"ChildCenterLocationList": [
{
"CenterLocationId": "4",
"CenterLocationName": "Stockton"
}
]
},
{
"TotalRecords": "372",
"StudentName": "John Luke",
"StudentImage": "",
"AnotherKey": "Another Value",
"AnotherKey1": "Another Value1",
"ClassDetail": [
{"class":"5","rollnumber":"123"},
{"class":"6","rollnumber":"456"},
{"class":"7","rollnumber":"678"}
],
"ChildCenterLocationList": [
{
"CenterLocationId": "4",
"CenterLocationName": "Stockton"
}
]
}
为此,我在控制器页面上写了简单的逻辑
exports.GetChildsDetail = async function (req, res) {
try {
let parms = [req.userId, req.query.Date];
let spRes = await _dbContaxt.ExcuteQuery(StoredProcdureName, parms);
if (spRes != null && spRes.length > 0) {
//till now everything is good. I am getting the response properly as I mentioned above and sending it to client
}
}
})
现在再次要求您必须使用 ClassDetail 键中的 rollnumber 为每个学生找到每个班级的主题详细信息和标记表详细信息。
所以 ClassDetail 键将类似于
"ClassDetail": [
{
"class":"5",
"rollnumber":"123",
"subjectDetail": [{'subject1detail'},{'subject1detail'},{'subject1detail'}]
"mrksheetDetail": [{'this is again an complex object'}]
},
{
"class":"6",
"rollnumber":"456",
"subjectDetail": [{'subject1detail'},{'subject1detail'},{'subject1detail'}]
"mrksheetDetail": [{'this is again an complex object'}]
}
{
"class":"7",
"rollnumber":"678",
"subjectDetail": [{'subject1detail'},{'subject1detail'},{'subject1detail'}]
"mrksheetDetail": [{'this is again an complex object'}]
}
]
所以我再次像上面那样做
exports.GetChildsDetail = async function (req, res) {
try {
let parms = [req.userId, req.query.Date];
let spRes = await _dbContaxt.ExcuteQuery(StoredProcdureName, parms);
if (spRes != null && spRes.length > 0) {
for (var clients of spRes.ResData) {
let arrSubCodes = [];
for (var authList of clients.ClassDetail) {
let parms1 = [req.userId, authList.rollnumber, req.query.Date];
let spRes1 = await _dbContaxt.ExcuteQuery(_StoredProcedureForSubject, parms1);
if (spRes1 != null && spRes1.length > 0) {
arrSubCodes.push(singleData1.ResData.SubjectDetail)
}
}
clients.subjectDetail= arrSubCodes;
}
}
}
})
结果来了,但它需要太多时间,几乎 2 分钟。我只有10个学生。所以我尝试了另一种更快的方法,但它只适用于循环的最后一个rollnumber。代码在调用主循环之后。
if (spRes != null && spRes.length > 0) {
await Promise.all( spRes.ResData.map(async (item) => {
return new Promise((resolve, reject) => {
for (var i in item.ClassDetail) {
let parms2 = [req.userId, item.ClassDetail[i].rollnumber];
_dbContaxt.ExcuteQuery(_dbHelper._StoredProcedureForSubject, parms2).then(spRes1=>{
if (spRes1 != null && spRes1.length > 0) {
item.ClassDetail[i].subjectDetail= spRes1.ResData;
resolve()
}
})
}
})
}))
}
此代码仅适用于最后一个 rollnumber。如果我在 ClassDetail 键中有多个记录,那么它仅适用于最后一条记录。
解决方案
正如@bergi所说,我已经尝试过并且工作正常
if (spRes != null && spRes.length > 0) {
await Promise.all( spRes.ResData.map(async (item) => {
for (var i in item.ClassDetail) {
let parms2 = [req.userId, item.ClassDetail[i].rollnumber];
let spRes1 = await _dbContaxt.ExcuteQuery(_dbHelper._StoredProcedureForSubject, parms2)
if (spRes1 != null && spRes1.length > 0) {
item.ClassDetail[i].subjectDetail= spRes1.ResData;
}
}
}))
}
推荐阅读
- android - 如何纠正Android共享元素过渡的过渡问题?
- docker - 在 Kitematic 中,“连接到主机网络”是什么意思?
- ocaml - 有没有办法在 OCaml 的列表中添加一个空元素?
- php - 在 Laravel 中使用表单上传图片时面临的问题
- javascript - 如何根据 ID 更新另一张纸上的行而不用空白单元格覆盖?
- android - 如何在 Android Studio 中修复“Gradle 错误:网络无法访问:连接”
- python - 使用 django 和引导类创建单选表单的问题
- react-native - 是否可以在 react-native-cli 启动的项目上使用 expo 启动画面
- javascript - 我定义了一些变量,我用它们来检索经纬度和经度,但在我将变量传递给另一个函数后不起作用
- javascript - 找不到 cookie 的目录位置