【问题标题】:How to execute multiple mongoose queries asynchronously and wait until all of them finish executing before sending response?如何异步执行多个 mongoose 查询并等到它们全部执行完毕后再发送响应?
【发布时间】:2021-03-19 08:56:50
【问题描述】:

提前致谢,但有人可以向我解释如何为我的请求的每个属性执行不同的查询吗?我正在尝试创建一个搜索侧边栏菜单, 当用户更改复选框值时,我会创建一个具有以下属性的对象:

    {
      "category": [
        "electronics",
        "clothing",
        "pets"
      ],
      "condition": [
        "old",
        "new"
      ]
    }

我想将查询推送到一组函数中,然后使用 async.parallel 执行它们。调用时,我想将每个查询的结果推送到一个包含所有查询结果的数组中。

router.get('', async function(req,res)
{
    var searchResults = [];
    if(req.query.filters)
    {

        const queryObj = JSON.parse(req.query.filters);
        var searchQueries = [];
        if(queryObj.category){
            searchQueries.push(async function (cb) {
                return await Rentals.find({/* SOME CONDITION */}).populate('-something').exec(function (err, docs) {
                    if (err) {
                        throw cb(err);
                    }

                    cb(null, docs);
                });
            })    
        }

        if(queryObj.condition){
            searchQueries.push(async function (cb) {
                return await Rentals.find({/* SOME CONDITION */}).populate('-something').exec(function (err, docs) {
                    if (err) {
                        throw cb(err);
                    }

                    cb(null, docs);
                });
            })    
        }


        async.parallel(searchQueries, function(err, foundRentals) {
            if (err) {
                throw err;
            }
            searchResults.push(foundRentals[0]); // result of searchQueries[0]
            searchResults.push(foundRentals[1]); // result of searchQueries[1]
            searchResults.push(foundRentals[2]); // result of searchQueries[2]

        })
    }
    res.json(searchResults);
});

返回 searchResults 时出现问题,我从服务器接收到一个空数组,但是在发送响应后,查询完成,并且在发送响应后得到结果。 如何同时执行所有查询并等到所有查询完成后再向客户端发送响应?

【问题讨论】:

标签: javascript node.js mongodb express asynchronous


【解决方案1】:

您的promise.all 代码版本如下所示:

router.get('', async function(req,res)
{
    try{
        let searchResults = [],
            categoryPromises = [],
            conditionPromises = [];

        if(req.query.filters)
        {

            const queryObj = JSON.parse(req.query.filters);
            if(queryObj.category && queryObj.category.length > 0){
                categoryPromises = queryObj.category.map(singleCategory=>{
                    return Rentals
                        .find({/* SOME CATEGORY? */})
                        .populate('-something')
                        .exec();
                });   
            }

            if(queryObj.condition && queryObj.condition.length > 0){
                conditionPromises = queryObj.category.map(singleCondition=>{
                    return Rentals
                        .find({/* SOME CONDITION */})
                        .populate('-something')
                        .exec();
                });   
            }

            searchResults.push(await categoryPromises);
            searchResults.push(await conditionPromises);

        }
        res.json(searchResults);
    }catch(e){
        // catch-all error handling here
    }
});

(您也可以使用 for 循环代替 .map 将它们推送到 categoryPromises 数组中)

【讨论】:

  • 对不起,如果“const categoryPromises”是在 if 中定义的,怎么可能把它推到 if 语句的范围之外?这和 Promises 有关系吗?
  • 不,你说得对,那是我的错。您需要在 if (fixed) 之外定义它
【解决方案2】:

我用这个语法解决了它

let finalResults = await Promise.all(arrayToIterate.map(async(value) => { // map instead of forEach
    const result = await getRentalsByQuery({query});
    finalValue = result;
    return finalValue; // important to return the value
}));

【讨论】:

    猜你喜欢
    • 2019-01-01
    • 2014-09-20
    • 1970-01-01
    • 2016-04-15
    • 1970-01-01
    • 1970-01-01
    • 2012-05-25
    • 2021-05-11
    • 2019-11-07
    相关资源
    最近更新 更多