首先,如果标题是荒谬的,我道歉。我只是很难解释我遇到的问题。
我正在尝试借助其他集合中的数据从集合中检索数据。通常情况下,在另一个查询中运行查询工作正常,但在混合中引入for循环使我难以修复。
所以,这就是我想要的 - 我在一个名为'all_collections'的数组中有一组对象。每个集合都包含另一个名为“资源”的数组。我的目标是在每个对象的索引0处检索'_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});
});
});
我也试过了 -
var output_collections = [];
User.findOne({ _id: req.session.userId }).then(function(user) {
output_collections.push(user);
for (var i = 0; i < user.all_collections.length; i++) {
Resource.findOne({ _id: user.all_collections[i].resources[0] })
.exec(function(error, resource) {
output_collections.push('div>'+resource.image+'</div')
});
}
console.log('1');
return Promise.all(output_collections);
}).then(function(output_collections) {
console.log(output_collections);
res.render('profile', {
title: 'Profile',
name: output_collections[0].name,
email: output_collections[0].email,
collections: output_collections
})
}).catch(function(error) {
next(error);
});
'output_collections'变量在for循环之外变为空。我很确定这是创建问题的for循环。如果有人能够正确地告诉我如何正确地做到这一点(如果这里的使用是完全错误的话),我将非常感激。
答案 0 :(得分: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})
})
答案 1 :(得分:0)
&#39; output_collections&#39;变量在for循环之外变为空。
这是因为Resource.findOne()
是一个异步调用,当它完成从db中获取数据时,res.render()
就已经完成了。
我相当肯定它是创造问题的for循环。如果有人能告诉我如何正确地做到这一点
是。你是对的。 for
循环异步任务,但期望以同步方式生成。您可以通过在Promise
Resource.findOne()
来更改此设置
对代码进行更改
'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});
}