我在返回列表时遇到问题。首先,我通过查询数据库将元素添加到列表中,一旦数据库查询完成,我就只返回列表。但是,我意识到查询是异步发生的,这段代码在完成查询所有数据并将其添加到列表之前就返回了。
我知道在其他语言中,我们可以使用 Mutex 或 Semaphore 来解决这个竞争条件问题,但我们如何在 Javascript 中处理这个问题?
let all_recipe= []
for(let i =0; i<result.chefs.email.length; ++i)
{
chefSchema['chef'].findOne({"email":result.chefs.email[i]},"recipe")
.then(recipes=>{
if(recipes!=null)
{
if(recipes.recipe.length!=0)
{
all_recipe.push(recipes.recipe);
}
}
console.log("Async Test1")
}).catch(err=>
{
console.log(err);
return res.status(500).json({
message:"Finding Chef Database Error!",
error: err
});
});
}
console.log("Async Test2")
console.log(all_recipe);
return res.status(200).json(all_recipe);
调试控制台输出:
Async Test2
[]
GET /store/ABC%20Pizza%20Store/getAllMenu 200 179.642 ms - 2
Async Test1
Async Test1
Async Test1
解决方案 添加异步/等待 promise :
storeSchema.findOne(req.params,"chefs").exec()
.then(async result=>{
if(result.length<1)
{
return res.status(409).json({
error_code:20,
message:"Store not registered by Manager yet"
});
}
else
{
let all_recipe= []
for(let i =0; i<result.chefs.email.length; ++i)
{
try{
let recipes = await chefSchema['chef'].findOne({"email":result.chefs.email[i]},"recipe").exec();
if(recipes!=null)
{
if(recipes.recipe.length!=0)
{
all_recipe.push(recipes.recipe);
}
}
}
catch(err)
{
return res.status(500).json({
message:"getAllMenu Database Error!"
});
}
}
console.log("Async Test2")
console.log(all_recipe);
return res.status(200).json(all_recipe);
最佳答案
备选方案之一是在将结果记录到控制台之前引入关键字 await
。它实际上会让 JavaScript 等待,直到 findOne
返回的 promise 完成并返回其结果。
使用这个link供引用。
我认为以下应该可行:
let all_recipe= []
for(let i =0; i<result.chefs.email.length; ++i)
{
await chefSchema['chef'].findOne({"email":result.chefs.email[i]},"recipe")
.then(recipes=>{
if(recipes!=null)
{
if(recipes.recipe.length!=0)
{
all_recipe.push(recipes.recipe);
}
}
console.log("Async Test1")
}).catch(err=>
{
console.log(err);
return res.status(500).json({
message:"Finding Chef Database Error!",
error: err
});
});
}
console.log("Async Test2")
console.log(all_recipe);
return res.status(200).json(all_recipe);
关于javascript - 如何推送到异步任务中的列表并仅在异步任务完成后才返回列表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49615904/