Представление представления в SailsJS после запроса цикла mongodb forEach

У меня есть 2 коллекции с именами "Ключевые слова" и "Компания", я использую агрегатную среду MongoDB для извлечения связанного object._id из базы коллекции "Ключевые слова" по ключу пользователя ключевых слов.

После того, как я получил object._id из коллекции ключевых слов, я хочу запросить и скомпилировать окончательные полные документы из коллекции Company, используя object._id.

Я застрял в той части, где res.view() запускается первым, прежде чем результат [] соберет все документы из коллекции Company.

Мне нужно помочь превратить мой код в синхронный подход. Пожалуйста, помогите мне. Ниже то, что я сделал.

Образец документа из коллекции "Ключевые слова"

{
"_id": ObjectID("52ac7130bd40d00a7beb7a29"),
"keyword": "Sunshine",
"object": [
    {
        "_id": ObjectID("528443ce751fc9b805d640ad"),
        "type": "companyName"
  }
]
}

Образец документа из коллекции "Компания"

{
"_id": ObjectID("528443ce751fc9b805d640ad"),
"name": "Sunshine Plaza",
...
...
...
}

SearchController в SailsJS

var keyWords = req.query.q,
    searchKeywords = keyWords.toLowerCase().replace(/[^\w\s]/gi, ' ').split(' '), //For example user key in "Sunshine Plaza"
    results = [];

    Keyword.native(function(err,collection){
        collection.aggregate([
            {
                $project : {
                    '_id' : 0,
                    'keyword' : 1,
                    'object' : 1
                }
            }, {
                $match : {
                    'keyword' : {
                        '$in' : searchKeywords
                    }
                }
            } , {
                $unwind : '$object'
            } , {
                $group : {
                    _id : '$object._id',
                    count : {
                        $sum : 1
                    }
                }
            } , {
                $sort : {
                    count: -1
                }
            } , {
                 $skip : 0
            } , {
                $limit : 10
            }
        ], function (err, docs){
            docs.forEach(function (doc, i){
                Company.findOne({
                    '_id' : doc._id
                },function(err,docs){
                    results.push(docs);
               });
            });
        });
    });

    res.view({
        key : keyWords,
        results : results,
        layout: "layouts/search"
    });

1 ответ

Что вы упускаете, так это то, что это не блокирует код.

Итак, следующее

setTimeout(function() {
    console.log('hi');
}, 2000);

console.log('bob');

Bob произойдет первым. затем hi, Это потому, что это не останавливает.

Таким образом, вы должны переписать эту часть вашего кода:

function (err, docs){
            docs.forEach(function (doc, i){
                Company.findOne({
                    '_id' : doc._id
                },function(err,docs){
                    results.push(docs);
               });
            });
        });
    });

    res.view({
        key : keyWords,
        results : results,
        layout: "layouts/search"
    });

На что-то вроде следующего:

function (err, docs){
        docs.forEach(function (doc, i){
            Company.findOne({
                '_id' : doc._id
            },function(err,docs){
                results.push(docs);   
           });
        }, myFunction());
    });
});
function myFunction() {
    res.view({key : keywords, results : results, layout: "layouts/search" });
}
Другие вопросы по тегам