我已经使用了这种方法,它应该会给我下面提到的预期输出。但是,由于异步执行,它给出了实际输出。所以,请帮我解决同样的问题。
看,我调用了一个异步函数,在里面我运行了三个嵌套的映射循环。在第三个循环中,我连接数据库并获取值。基于该值,我生成Object的值,该值最初为空。一旦函数被调用,它就会触发then方法。这就是问题出现的地方,我需要在调用的函数完全执行之后再执行该函数。这是完整的问题陈述
给定以下代码:
let messageObject = {};
async function storeManager() {
// storing the defects or modifying
console.log('hii from storeManager()');
await Promise.all(
Object.keys(filledDefects).map((defectName) => {
Object.keys(filledDefects[defectName]).map((subDefectName) => {
Object.keys(filledDefects[defectName][subDefectName]).map(
async (zone) => {
const result = await dbConnectedPool.query(
`SELECT * FROM defect_table WHERE body_number=${enteredBodyNumber} AND category='${selectedCategory}' AND subcategory='${selectedSubCategory}' AND defect='${defectName}' AND subdefect='${subDefectName}' AND zone = ${zone.replace(
'_',
''
)}`
);
if (result.rows.length == 0) {
// block to save defects record for the first time
console.log(
`INSERT INTO defect_table (body_number,mode,category,subcategory,defect,subdefect,zone,defectCount,date,time,username) VALUES (${enteredBodyNumber},'${mode}','${selectedCategory}','${selectedSubCategory}','${defectName}','${subDefectName}',${zone.replace(
'_',
''
)},${
filledDefects[defectName][subDefectName][zone]
},'${date}','${time}','${username}');`
);
await dbConnectedPool.query(
`INSERT INTO defect_table (body_number,mode,category,subcategory,defect,subdefect,zone,defectCount,date,time,username) VALUES (${enteredBodyNumber},'${mode}','${selectedCategory}','${selectedSubCategory}','${defectName}','${subDefectName}',${zone.replace(
'_',
''
)},${
filledDefects[defectName][subDefectName][zone]
},'${date}','${time}','${username}');`
);
mod.set(
messageObject,
`Newly Saved Zone.${zone}.${defectName}.${subDefectName}`,
filledDefects[defectName][subDefectName][zone]
);
console.log('inside: ', messageObject);
} else {
// block to modify existing defect records
console.log(
`UPDATE defect_table SET defectCount=${
filledDefects[defectName][subDefectName][zone]
},date='${date}',time='${time}',username='${username}' WHERE body_number=${enteredBodyNumber} AND category='${selectedCategory}' AND subcategory='${selectedSubCategory}' AND defect='${defectName}' AND subdefect='${subDefectName}' AND zone=${zone.replace(
'_',
''
)}`
);
await dbConnectedPool.query(
`UPDATE defect_table SET defectCount=${
filledDefects[defectName][subDefectName][zone]
},date='${date}',time='${time}',username='${username}' WHERE body_number=${enteredBodyNumber} AND category='${selectedCategory}' AND subcategory='${selectedSubCategory}' AND defect='${defectName}' AND subdefect='${subDefectName}' AND zone=${zone.replace(
'_',
''
)}`
);
mod.set(
messageObject,
`Overwritten Zone.${zone}.${defectName}.${subDefectName}`,
filledDefects[defectName][subDefectName][zone]
);
console.log('inside: ', messageObject);
}
// checking whether already record exists with same aspects
}
);
});
})
);
console.log('bye from storeManager()');
}
storeManager().then(() => {
console.log('message outside:', messageObject);
});
预期输出:
hii from storeManager()
bye from storeManager()
UPDATE defect_table SET defectCount=12,date='2022-10-12',time='12:52:33',username='Vasanth'
WHERE body_number=1234 AND category='LH SHELL BODY MAIN-LINE' AND subcategory='FENDER - LH
SBML' AND defect='Surface' AND subdefect='Dent' AND zone=210
inside: { 'Overwritten Zone': { _210: { Surface: [Object] } } }
UPDATE defect_table SET defectCount=12,date='2022-10-12',time='12:52:33',username='Vasanth'
WHERE body_number=1234 AND category='LH SHELL BODY MAIN-LINE' AND subcategory='FENDER - LH
SBML' AND defect='Surface' AND subdefect='Dent' AND zone=215
inside: {
'Overwritten Zone': { _210: { Surface: [Object] }, _215: { Surface: [Object] } }
}
message outside: {
'Overwritten Zone': { _210: { Surface: [Object] }, _215: { Surface: [Object] } }
}
实际输出:
hii from storeManager()
bye from storeManager()
message outside: {}
UPDATE defect_table SET defectCount=12,date='2022-10-12',time='12:52:33',username='Vasanth'
WHERE body_number=1234 AND category='LH SHELL BODY MAIN-LINE' AND subcategory='FENDER - LH
SBML' AND defect='Surface' AND subdefect='Dent' AND zone=210
inside: { 'Overwritten Zone': { _210: { Surface: [Object] } } }
UPDATE defect_table SET defectCount=12,date='2022-10-12',time='12:52:33',username='Vasanth'
WHERE body_number=1234 AND category='LH SHELL BODY MAIN-LINE' AND subcategory='FENDER - LH
SBML' AND defect='Surface' AND subdefect='Dent' AND zone=215
inside: {
'Overwritten Zone': { _210: { Surface: [Object] }, _215: { Surface: [Object] } }
}
在生成promise数组的任何地方都需要使用Promise.all
,而不仅仅是在最外层的调用上。您需要让map
回调真正返回这些承诺!
await Promise.all(Object.entries(filledDefects).map(async ([defectName, defect]) => {
await Promise.all(Object.entries(defect).map(async ([subDefectName, subDefect]) => {
await Promis.all(Object.entries(subDefect).map(async ([zoneName, zone]) => {
await …;
}));
}));
}));
或者,你也可以在没有async
/await
:的情况下写这篇文章
await Promise.all(Object.entries(filledDefects).map(([defectName, defect]) =>
Promise.all(Object.entries(defect).map(async ([subDefectName, subDefect]) =>
Promis.all(Object.entries(subDefect).map(async ([zoneName, zone]) => {
await …;
}));
));
));
Promise.all
需要一个promise数组作为参数,但您却向它传递了一个未定义值的数组。这意味着Promise.all
将返回一个立即解决的承诺。
导致此问题的两个原因:
- 外部
map
回调没有return
语句(因此它们将每个defectName
和每个subDefectName
映射到undefined
( - 如果将
return
作为内部.map
调用的结果,那么每个defectName
都映射到一个数组(数组…(,这仍然不是您所需要的。您不想要嵌套数组,而是平面数组,所以使用return Object.keys().flatMap
而不是Object.keys().map