【问题标题】:How do I execute a code only once all the queries inside a loop are done? (mongoose, express)仅在循环内的所有查询都完成后,如何执行代码? (猫鼬,快递)
【发布时间】:2022-02-14 06:57:08
【问题描述】:

这是我的路由器:

router.get('/questions/best', function(req,res,next){
  Question.aggregate([
    // Protect against missing fields with $ifNull                                                         
    // Protect against division by zero dislikes using max[1,size]                                         
    {$project: {ratio: {$divide:[
    {$arrayElemAt:[{$ifNull:["$likes",[0]]}, 0]},
        {$max:[1, {$arrayElemAt:[{$ifNull:["$dislikes",[0]]}, 0]}]}
        ]}
    }},
    {$sort: {ratio:-1}},
    {$limit: 15}
  ]).exec(function(err,results){
    if(err) {return next(err)}
    top15 = []
    for(let i = 0; i < results.length; i++){
      Question.findOne({_id: results[i]._id}).exec(function(err,result){
        if(err){return next(err)}
        top15.push(result);
      })
    }
    res.render('content', { whichOne: 5, user: req.user, questions: top15 });
  });
});

不用担心过滤的东西,它工作得很好,唯一的问题是路由器末尾的模板会在查询开始后立即自动呈现,不允许他们有时间将结果推送到一个数组中被渲染到模板中。 我尝试使用 set Timeout 功能,但处理时间发生了巨大变化,无法找到准确的时间。我想我需要使用异步功能?但是由于某种原因,承诺不起作用?

任何人都可以确保模板仅在所有查询返回并将其值放入数组后才呈现? 谢谢!

【问题讨论】:

  • but promises do not work for some reason? 你没有在你发布的代码中使用 Promise - 你可能试图错误地使用 Promise,因为 Promise 让这个任务变得微不足道
  • 是的,我是,文档没有对这类事情给出任何很好的解释,这就是我在这里的原因。
  • 为什么你在Question 集合上运行aggregate 方法,然后在for 循环中使用find 方法再次查询同一个集合?您可以使用单个 aggregate 方法对集合执行这两个操作。

标签: javascript mongodb express mongoose promise


【解决方案1】:

通过阅读 mongoose documentation,使用 Promise 让这变得微不足道

使用承诺

router.get('/questions/best', (req,res,next) => {
    Question.aggregate([
        // Protect against missing fields with $ifNull                                                         
        // Protect against division by zero dislikes using max[1,size]                                         
        {$project: {ratio: {$divide:[
        {$arrayElemAt:[{$ifNull:["$likes",[0]]}, 0]},
            {$max:[1, {$arrayElemAt:[{$ifNull:["$dislikes",[0]]}, 0]}]}
            ]}
        }},
        {$sort: {ratio:-1}},
        {$limit: 15}
    ]).exec()
    .then(results => Promise.all(results.map(({_id}) => Question.findOne({_id}).exec())))
    .then(questions => res.render('content', { whichOne: 5, user: req.user, questions}))
    .catch(next);
});

或者,使用异步/等待

router.get('/questions/best', async (req,res,next) => {
    try {
        const results = await Question.aggregate([
            // Protect against missing fields with $ifNull                                                         
            // Protect against division by zero dislikes using max[1,size]                                         
            {$project: {ratio: {$divide:[
            {$arrayElemAt:[{$ifNull:["$likes",[0]]}, 0]},
                {$max:[1, {$arrayElemAt:[{$ifNull:["$dislikes",[0]]}, 0]}]}
                ]}
            }},
            {$sort: {ratio:-1}},
            {$limit: 15}
        ]).exec();
        const questions = await Promise.all(results.map(({_id}) => Question.findOne({_id}).exec()));
        res.render('content', { whichOne: 5, user: req.user, questions});
    } catch(err) {
        next(err);
    }
});

【讨论】:

    猜你喜欢
    • 2017-12-13
    • 1970-01-01
    • 2021-08-10
    • 1970-01-01
    • 1970-01-01
    • 2017-06-04
    • 2022-01-10
    • 1970-01-01
    • 2016-11-19
    相关资源
    最近更新 更多