等待foreach完成NodeJS

时间:2019-06-01 16:51:18

标签: node.js mongoose

因此,我正在NodeJS中创建一个API。在一个API中,我必须在猫鼬查询中调用循环。

如何在执行res.send()之前等待forEach完成?我在下面附加了我的代码。

router.post("/getResult", function (req, res) {
    const lottery_id = req.body.lottery_id;
    const prizeQuery = Prize.find({"lotid": lottery_id});

    let response = [];

    prizeQuery.exec(function (err, prizes) {
        console.log(prizes.length);
        if (err) return res.send({success: 0, data: err});
        else {
            prizes.forEach(prize => {
                let prizeData = {};
                const winnerQuery = Winner.find({"id": prize._id});
                winnerQuery.exec(function (err, winners) {
                    if (err) return res.send({success: 0, data: err});
                    else {
                        prizeData = {
                            prize: prize,
                            winners: winners
                        };
                        response.push(prizeData);
                    }
                });
            });
        }
    });
    return res.send({success:1, data: response});
});

在上面的代码中,在forEach完成之前调用return。

2 个答案:

答案 0 :(得分:3)

由于您正在forEach中运行异步代码,并且forEach不会等到异步代码完成,因此,必须用等待的原语包装异步代码。

在失败的情况下,您提供的代码也会调用send两次,因为forEach内部的返回实际上不会结束封闭函数。

try {
    await Promise.all(prizes.map(async (prize) => {
        const winners = await Winner.find({"id": prize._id});
        response.push({prize, winners});
    }))
    res.send({success:1, data: response});
} catch (err) {
    res.send({success: 0, data: err});
}

答案 1 :(得分:0)

@Rami的答案是正确的,但除此之外,您还可以使用forof来使代码正常工作。 forof同步工作,因此不需要承诺。喜欢

          for (let prize of prizes){
                let prizeData = {};
                try{
                  const winnerQuery = Winner.find({"id": prize._id});
                  const winners = await winnerQuery.exec()
                  prizeData = {
                              prize: prize,
                              winners: winners
                          };
                  response.push(prizeData);   
                }catch(err){
                 console.error(err)
                }
            }