我有方法:
const getTaskOrCategoryRecursive = async (type, id)=>{
const rslt = await type.findOne.call(type, {_id:id},{}, standardOptions, err=>{
if(err){
return({err: err});
}
});
const result = rslt.toObject();
const tasks = result.tasks;
const events = result.events;
result.children = {};
result.children.tasks = tasks.map(async taskId=>{
const taskIdString = taskId.toString();
const rtrn = await getTaskRecursive(taskIdString, err=>{
if(err){
return({err: err});
}
});
return rtrn;
});
result.children.events = events.map(async eventId=>{
const eventIdString = eventId.toString();
await Event.findOne({_id:eventIdString}, standardOptions,err=>{
if(err){
return({err: err});
}
});
});
return result;
}
有两种方法调用它:
const getTaskRecursive = (taskId)=>{
return getTaskOrCategoryRecursive(Task, taskId)
}
和
const getCategoryRecursive=(categoryId)=>{
return getTaskOrCategoryRecursive(Category,categoryId);
};
由函数调用
router.get('/:id', verifyToken, async (req,res)=>{
Branch.getCategoryRecursive(req.params.id)
.then(
(cat)=>{
res.status(200).send(cat);
},
(err)=>{
res.status(500).send(err);
}
)
});
当我尝试运行程序时,首先运行getCategoryRecursive
方法,然后运行res.status(200).send(cat);
,然后运行getTasksRecursive
方法,该方法获取响应中要发送的对象的子级。 getTasksRecursive
执行了应有的操作,但是在发送响应后它正在运行,因此该对象为空。
如何在发送响应之前使异步方法运行?
更新:使用Aritra Chakraborty的答案,我将其更改为以下内容,并且可以正常工作。
首先,我将.map
分解为一个新函数:
const getAllTasksRecursive = async(taskIds)=>{
const rtrn = await Promise.all(
taskIds.map(
async taskId=>{
return await getTaskRecursive(taskId.toString(), err=>{if(err){return {err:err}}});
}
)
)
return rtrn;
}
然后我在上一个函数中使用:
result.children.tasks = await getAllTasksRecursive(tasks);
现在,我将数据返回到响应中。
答案 0 :(得分:1)
那是因为内部的map
或foreach
看起来像这样:
Array.prototype.forEach = function (callback) {
// this represents our array
for (let index = 0; index < this.length; index++) {
// We call the callback for each entry
callback(this[index], index, this)
}
}
它会正确调用回调,但是在运行下一个回调之前不会等待回调完成。
因此,您需要一个async foreach
,
async function asyncForEach(array, callback) {
for (let index = 0; index < array.length; index++) {
await callback(array[index], index, array)
}
}
请注意,如何await
进行回调。
您的代码必须是这样的:
const start = async () => {
await asyncForEach([1, 2, 3], async (num) => {
await waitFor(50)
console.log(num)
})
console.log('Done')
}
start()
引用:https://codeburst.io/javascript-async-await-with-foreach-b6ba62bbf404这篇文章过去对我有很大帮助。