我对这段代码有一些问题。 因此,我使用Mongoose从我的数据库中获取数据,然后我想将一段数据推送到一个名为“作者”的数组中。然后单独使用该数据。
我可以访问数据,因为如果我使用console.log()调试它,但是我无法在while循环之外获取该数据。发生了什么?
最后一行以' []'
回应 while (i < 8) {
var search = User.find({'twitter.id' : collected[i].author});
search.exec(function (err, user){
if (err) return console.error(err);
var result = (user[0].twitter.username);
authors.push(result);
});
i = i + 1;
}
console.log(authors);
答案 0 :(得分:2)
由于Javascript是异步的,即使循环仍在运行,也会执行console.log(authors)
。
要在js中处理异步,您可以使用此async模块,它非常强大且易于使用。
---编辑
var _ = require('lodash');
var authors;
User.find({ "twitter.id" : {$in: _.map(collected, 'author')}}).exec()
.then(function(docs) {
author = docs;
// Do something
})
我认为你可以这样做,它与@inspired
基本相同答案 1 :(得分:2)
最后一行以&#39; []&#39;
回应
这是因为User.find()
是async
电话。因此,当您在i = 8
时退出循环时,您将在数据返回之前点击console.log(authors)
。
当您只需要进行8
调用时,您似乎正在对数据库进行1
次单独调用。如果你有一个名为collected
的数组,你正在循环。它看起来像这样。
var collected = [
{ author : "23423423"},
{ author : "23423424"},
{ author : "23423425"},
{ author : "23423426"},
];
您可以使用.map功能收集所有Twitter ID。
var twitterIds = collected.map(function(a){return a.author});
现在twitterIds == ["23423423", "23423424", "23423425", "23423426"]
。
然后,您可以使用$in运算符选择twitter.id
的值等于指定数组中任何值的文档。
然后,您可以执行此操作User.find({ "twitter.id" : {$in : twitterIds}});
它将返回一个文档,其中包含您可以操作的所有匹配文档。现在,您已减少为1
来电而非8
。
我会用以下两种方式之一重构代码:
1)返回查询
function search(twitterIds){
var query = User.find({ "twitter.id" : twitterIds});
return query;
}
然后您可以这样使用它:
var searchQuery = search(twitterIds);
searchQuery.exec(function(err,users){
if(err) return console.log(err);
//do something with users..
users.forEach(function(user){
console.log(user.twitter.username);// do something here
});
}
2)退回承诺
function search(twitterIds){
var promise = User.find({ "twitter.id" : twitterIds}).exec();
return promise;
}
然后您可以这样使用它:
var promise = search(twitterIds);
promise.then(function(users){
//do something...
}).error(function(err){
console.log(errr);
});
在使用async库之前,我会从这里开始看看是否可以完成工作。