Node.js 如何在for循环中运行mongoose查询并使res.render等待

Node.js 如何在for循环中运行mongoose查询并使res.render等待,node.js,mongoose,Node.js,Mongoose,首先,如果这个标题是荒谬的,我道歉。我只是很难解释我有什么问题 我试图在另一个集合的数据的帮助下从一个集合中检索数据。通常,在另一个查询中运行一个查询效果很好,但在混合中引入for循环使我难以修复 所以,我想说的是,我在一个名为“all_collections”的数组中有一个对象集合。每个集合都包含另一个名为“资源”的数组。我的目标是在每个对象的索引0处检索“\u id” 这就是我所尝试的- router.get('/profile', mid.requiresLogin, functi

首先,如果这个标题是荒谬的,我道歉。我只是很难解释我有什么问题

我试图在另一个集合的数据的帮助下从一个集合中检索数据。通常,在另一个查询中运行一个查询效果很好,但在混合中引入for循环使我难以修复

所以,我想说的是,我在一个名为“all_collections”的数组中有一个对象集合。每个集合都包含另一个名为“资源”的数组。我的目标是在每个对象的索引0处检索“\u id”

这就是我所尝试的-

    router.get('/profile', mid.requiresLogin, function(req, res, next) {
        var output_collections = '';
        User.findOne({ _id: req.session.userId }, function(err, user) {
            for(var i=0; i<user.all_collections.length;i++) {
                Resource.findOne({_id:user.all_collections[i].resources[0]}, function(err, resource) {
                    output_collections += '<div>'+resource.image+'</div>';
                })
            }

        res.render('profile',{collections:output_collections});
     });
  });
router.get('/profile',mid.requiresLogin,函数(req,res,next){
var输出_集合=“”;
findOne({u id:req.session.userId},函数(err,User){
对于(var i=0;i'+resource.image+'
router.get('/profile',mid.requiresLogin,async(req,res,next)=>{
让输出_集合=[]
let user=wait user.findOne({u id:req.session.userId})
for(设i=0;i
“output_collections”变量在for循环外部为空

这是因为
Resource.findOne()
是一个异步调用,当它完成从db绑定数据时,
res.render()
将已经完成

我相当肯定是for循环造成了问题。如果有人能告诉我如何正确地做到这一点

是的。你说得对。
for
循环异步任务,但预期结果是同步的。你可以通过在

对代码进行这些更改

'use strict';

let _ = require('lodash');

getUserDetailById(req.session.userId).then(user => {
  return Promise.all([
    user,
    getResourceDetailsForUser(user.all_collections)
  ]);
}).then(results => {
  let [{name, email}, collections] = results;
  res.render('profile', {
    title: 'Profile',
    name: name,
    email: email,
    collections: collections
  });
}).catch(err => {
  console.log('Error occured when fetching resource', err);s
});

function getResourceDetailsForUser(collections) {
  if (_.isEmpty(collections)) {
    return [];
  }

  return _.map(collections, collection => {
    return Resource.findOne({
      _id: collection.resources[0]
    }).then((error, resource) => {
      return `<div>${resource.image}</div>`;
    });
  });
}

function getUserDetailById(userId) {
  return User.findOne({_id: userId});
}
“严格使用”;
让uz=require('lodash');
getUserDetailById(req.session.userId)。然后(user=>{
回报你的承诺([
用户,
getResourceDetailsForUser(用户.所有集合)
]);
})。然后(结果=>{
让[{name,email},collections]=结果;
res.render('profile'{
标题:“个人资料”,
姓名:姓名,,
电邮:电邮,,
收藏:收藏
});
}).catch(错误=>{
console.log('获取资源时出错',err);s
});
函数getResourceDetailsForUser(集合){
如果(uu.isEmpty(集合)){
返回[];
}
return>map(集合,集合=>{
return Resource.findOne({
_id:集合。资源[0]
}).然后((错误,资源)=>{
返回`${resource.image}`;
});
});
}
函数getUserDetailById(userId){
返回User.findOne({u id:userId});
}

您的代码是正确的。出现了什么问题?变量输出集合在for循环之外是空的。我的理解是res.render是在填充变量之前执行的。您好,Sridhar。感谢您花时间给我如此详细的答案。但是,它到目前为止还不起作用,主要原因是没有o我不了解您提供的代码。在GetResourceDetailsForser函数中,它是否在遍历collections对象?因为它应该根据用户的长度遍历每个集合。all_collections-collection[0]。resource[0]collection[1}。resource[0]@RajSaha是,它在集合[i]上进行迭代.资源[0]。
router.get('/profile', mid.requiresLogin, async (req, res, next) => {
    let output_collections = []
    let user = await  User.findOne({ _id: req.session.userId })

    for(let i=0; i<user.all_collections.length;i++) {
         let rerource = await Resource.findOne({_id:user.all_collections[i].resources[0]})
         output_collections.push('<div>'+ resource.image+'</div>')

    }
    res.render('profile',{collections:output_collections})
})
'use strict';

let _ = require('lodash');

getUserDetailById(req.session.userId).then(user => {
  return Promise.all([
    user,
    getResourceDetailsForUser(user.all_collections)
  ]);
}).then(results => {
  let [{name, email}, collections] = results;
  res.render('profile', {
    title: 'Profile',
    name: name,
    email: email,
    collections: collections
  });
}).catch(err => {
  console.log('Error occured when fetching resource', err);s
});

function getResourceDetailsForUser(collections) {
  if (_.isEmpty(collections)) {
    return [];
  }

  return _.map(collections, collection => {
    return Resource.findOne({
      _id: collection.resources[0]
    }).then((error, resource) => {
      return `<div>${resource.image}</div>`;
    });
  });
}

function getUserDetailById(userId) {
  return User.findOne({_id: userId});
}