如何异步执行多个猫鼬查询,并等到它们全部执行完毕后再发送响应?

时间:2018-12-07 01:38:23

标签: javascript node.js mongodb express asynchronous

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

    {
      "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时出现问题,我从服务器接收到一个空数组,但是在发送响应后查询完成,并且在发送AFTER响应后得到结果。 如何在同一时间执行所有查询,并等到所有查询完成后再向客户端发送响应?

2 个答案:

答案 0 :(得分:0)

您的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
    }
});

(除了.map之外,您还可以使用for循环将其推送到categoryPromises数组中)

答案 1 :(得分:0)

我用这种语法解决了它

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