Node.js 节点中的异步函数仅在发送响应后运行

Node.js 节点中的异步函数仅在发送响应后运行,node.js,express,asynchronous,Node.js,Express,Asynchronous,我的方法是: const getTaskOrCategoryRecursive = async (type, id)=>{ const rslt = await type.findOne.call(type, {_id:id},{}, standardOptions, err=>{ if(err){ return({err: err}); } }); const result = rslt.toObje

我的方法是:

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)

}

由函数调用的

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);

现在,我将数据返回到响应中。

这是因为在内部,
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)
  }
}
const start = async () => {
  await asyncForEach([1, 2, 3], async (num) => {
    await waitFor(50)
    console.log(num)
  })
  console.log('Done')
}
start()
注意,回调是如何等待的

您的代码必须如下所示:

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)
  }
}
const start = async () => {
  await asyncForEach([1, 2, 3], async (num) => {
    await waitFor(50)
    console.log(num)
  })
  console.log('Done')
}
start()
参考:这篇文章在过去对我帮助很大