异步:在回调内部的 For 之后获取空数组
Async : Get empty array after For inside the callback
我尝试将数据库查询的结果存储在一个数组中,但我得到的总是一个空数组。我不太了解 Async 是如何工作的,但我认为这段代码应该可以工作,因为我在完成之前存储了变量
注意:下面也是一个数组,我知道这个问题是因为异步行为,但我不知道如何解决它
代码:
exports.getfollowingUser = function(req, res){
followedUser=[];
following = req.user.follow;
for (i = 0; i < following.length; i++) {
User.find(following[i].followed, function (err, followUser){
followedUser[i]= followUser;
});
}
console.log(followedUser) // result empty
res.render('following', {
followedUser: followedUser
});
};
编辑:1遵循架构
module.exports = mongoose.model('Friendship',{
follower: String,
followed: String
});
编辑:2 用户模式
module.exports = mongoose.model('User',{
email:{
type: String,
unique: true,
lowercase: true },
password:String,
profile:{
fullname: String,
gender: String,
role: {type: String, default: 'Autorizado'},
country: String },
});
注意:我正在尝试获取用户(登录)关注的朋友并在视图中显示他们。
看执行流程:
exports.getfollowingUser = function(req, res){
followedUser=[]; // 1
following = req.user.follow;
for (i = 0; i < following.length; i++) {
User.find(following[i].followed, function (err, followUser){ // 2,3,4
followedUser[i]= followUser; // 7,8,9
});
}
console.log(followedUser) // result empty // 5
res.render('following', {followedUser: followedUser}); // 6
};
如您所见,在您执行 console.log
[5] 时,followedUser[i]= followUser
尚未执行 [7,8,9]。这就是你得到空数组的原因。
这是您可以解决的方法
exports.getfollowingUser = function(req, res){
followedUser=[]; // 1
following = req.user.follow;
var counter = 0;
var length = following.length;
for (i = 0; i < following.length; i++) {
User.find(following[i].followed, function (err, followUser){ // 2,3,4
followedUser[i]= followUser; // 7,8,9
counter++;
if(counter>=length) allDone(); // 10
});
}
console.log(followedUser) // result empty // 5
res.render('following', {followedUser: followedUser}); // 6
function allDone(){
console.log(followedUser) // result empty // 11
res.render('following', {followedUser: followedUser}); // 12
}
};
此处相同的语句,但在 allDone()
[11,12] 内,它们将执行您期望它们执行的操作,因为它们在 [7,8,9].
之后执行
这只是为了解释,有更好的库来处理这样的事情:
也有帮助:https://blog.engineyard.com/2015/taming-asynchronous-javascript-with-async
在您的 for 循环中 node
只需向您的数据库发出请求并继续处理。它不等待数据库的结果。这就是异步的工作原理。因此,在您的 for 循环 node
尚未收到来自数据库的结果并且 followedUser
为空之后。要在没有第三方库的情况下解决此问题,您可以执行以下操作:
exports.getfollowingUser = function(req, res){
findFollowedUser(req.user.follow, function(error, followedUser) {
console.log(followedUser);
res.render('following', {
followedUser: followedUser
});
});
function findFollowedUser(following, callback) {
var followedUser=[];
var waiting = following.length;
var wasError = false;
for (var i = 0; i < following.length; i++) {
User.find(following[i].followed, function (err, followUser){
if (wasError) {
return;
}
if (err) {
wasError = err;
return callback(err);
}
followedUser[i]= followUser;
waiting--;
if (!waiting) {
callback(null, followedUser);
}
});
}
}
};
另一种方法(我认为更好)是使用一些流控制库。例如:
我个人的喜好:bluebird - 极快的承诺实现。实际上 promises 是即将推出的 javascript 标准。所以我建议你仔细看看它。
另外,我建议您观看 this video。这是对 javascript 异步模型(事件循环如何工作)的非常简化的解释。
我尝试将数据库查询的结果存储在一个数组中,但我得到的总是一个空数组。我不太了解 Async 是如何工作的,但我认为这段代码应该可以工作,因为我在完成之前存储了变量
注意:下面也是一个数组,我知道这个问题是因为异步行为,但我不知道如何解决它
代码:
exports.getfollowingUser = function(req, res){
followedUser=[];
following = req.user.follow;
for (i = 0; i < following.length; i++) {
User.find(following[i].followed, function (err, followUser){
followedUser[i]= followUser;
});
}
console.log(followedUser) // result empty
res.render('following', {
followedUser: followedUser
});
};
编辑:1遵循架构
module.exports = mongoose.model('Friendship',{
follower: String,
followed: String
});
编辑:2 用户模式
module.exports = mongoose.model('User',{
email:{
type: String,
unique: true,
lowercase: true },
password:String,
profile:{
fullname: String,
gender: String,
role: {type: String, default: 'Autorizado'},
country: String },
});
注意:我正在尝试获取用户(登录)关注的朋友并在视图中显示他们。
看执行流程:
exports.getfollowingUser = function(req, res){
followedUser=[]; // 1
following = req.user.follow;
for (i = 0; i < following.length; i++) {
User.find(following[i].followed, function (err, followUser){ // 2,3,4
followedUser[i]= followUser; // 7,8,9
});
}
console.log(followedUser) // result empty // 5
res.render('following', {followedUser: followedUser}); // 6
};
如您所见,在您执行 console.log
[5] 时,followedUser[i]= followUser
尚未执行 [7,8,9]。这就是你得到空数组的原因。
这是您可以解决的方法
exports.getfollowingUser = function(req, res){
followedUser=[]; // 1
following = req.user.follow;
var counter = 0;
var length = following.length;
for (i = 0; i < following.length; i++) {
User.find(following[i].followed, function (err, followUser){ // 2,3,4
followedUser[i]= followUser; // 7,8,9
counter++;
if(counter>=length) allDone(); // 10
});
}
console.log(followedUser) // result empty // 5
res.render('following', {followedUser: followedUser}); // 6
function allDone(){
console.log(followedUser) // result empty // 11
res.render('following', {followedUser: followedUser}); // 12
}
};
此处相同的语句,但在 allDone()
[11,12] 内,它们将执行您期望它们执行的操作,因为它们在 [7,8,9].
这只是为了解释,有更好的库来处理这样的事情:
也有帮助:https://blog.engineyard.com/2015/taming-asynchronous-javascript-with-async
在您的 for 循环中 node
只需向您的数据库发出请求并继续处理。它不等待数据库的结果。这就是异步的工作原理。因此,在您的 for 循环 node
尚未收到来自数据库的结果并且 followedUser
为空之后。要在没有第三方库的情况下解决此问题,您可以执行以下操作:
exports.getfollowingUser = function(req, res){
findFollowedUser(req.user.follow, function(error, followedUser) {
console.log(followedUser);
res.render('following', {
followedUser: followedUser
});
});
function findFollowedUser(following, callback) {
var followedUser=[];
var waiting = following.length;
var wasError = false;
for (var i = 0; i < following.length; i++) {
User.find(following[i].followed, function (err, followUser){
if (wasError) {
return;
}
if (err) {
wasError = err;
return callback(err);
}
followedUser[i]= followUser;
waiting--;
if (!waiting) {
callback(null, followedUser);
}
});
}
}
};
另一种方法(我认为更好)是使用一些流控制库。例如:
我个人的喜好:bluebird - 极快的承诺实现。实际上 promises 是即将推出的 javascript 标准。所以我建议你仔细看看它。
另外,我建议您观看 this video。这是对 javascript 异步模型(事件循环如何工作)的非常简化的解释。