Jer*_*oen 14 javascript foreach asynchronous synchronous node.js
我目前正在与3个朋友一起使用nodeJs,expressJs,MongoDB,html5进行一个项目......由于我们对这些技术还不熟悉,我们遇到了一些问题.我无法找到解决方案的一个大问题是某些代码的异步执行.
我想要为每个循环完成,以便我有一个更新的在线好友列表,然后执行res.render(我在其中传递在线好友列表),因为当前它在完成循环之前执行res.render .码:
function onlineFriends(req, res) {
var onlinefriends = new Array();
onlinefriends.push("mark");
FriendList.findOne({
owner: req.session.username
}, function (err, friendlist) {
friendlist.friends.forEach(function (friend) { // here forEach starts
OnlineUser.findOne({
userName: friend
}, function (err, onlineFriend) {
if (onlineFriend != null) {
onlinefriends.push(onlineFriend.userName);
console.log("a loop");
}
});
});
console.log("online friends: " + onlinefriends);
console.log("redirecting");
res.render('index', { // this is still inside the forEach function
friendlist: friendlist.friends,
onlinefriendlist: onlinefriends,
username: req.session.username
});// and here it ends
});
Run Code Online (Sandbox Code Playgroud)
}
输出如下:
online friends: mark
redirecting
a loop
a loop
a loop
a loop
a loop
a loop
a loop
Run Code Online (Sandbox Code Playgroud)
正如这里所讨论的(JavaScript,Node.js:是Array.forEach异步吗?),答案是for-each是阻塞的,但在我的例子中,它似乎是非阻塞的,因为它在它之前执行res.render完成循环?我如何确保每个人都完成了所以我有一个最新的在线朋友列表(和朋友列表)我可以传递给res.render而不是res.render发生方式在for -each循环结束之前(这给了我一个不正确的在线用户列表)?
非常感谢!
BFi*_*Fil 15
以下控制台日志:
console.log("a loop");
Run Code Online (Sandbox Code Playgroud)
在回调中
我相信函数OnlineUser.findOne()的回调是异步调用的,这就是为什么代码会在重定向日志之后记录"循环"的原因
在执行完所有循环回调后,应该重定向
就像是:
var count = 0;
friendlist.friends.forEach(function (friend) { // here forEach starts
OnlineUser.findOne({
userName: friend
}, function (err, onlineFriend) {
count++;
if (onlineFriend != null) {
onlinefriends.push(onlineFriend.userName);
console.log("a loop");
}
if(count == friendlist.friends.length) { // check if all callbacks have been called
redirect();
}
});
});
function redirect() {
console.log("online friends: " + onlinefriends);
console.log("redirecting");
res.render('index', { // this is still inside the forEach function
friendlist: friendlist.friends,
onlinefriendlist: onlinefriends,
username: req.session.username
});// and here it ends
}
Run Code Online (Sandbox Code Playgroud)
小智 6
通过将async包添加到我的项目并将forEach()更改为async.each(),我能够解决类似问题.优点是,这提供了一种与应用程序的其他部分进行同步的标准方法.
你的项目有这样的东西:
function onlineFriends(req, res) {
var onlinefriends = new Array();
onlinefriends.push("mark");
FriendList.findOne({owner: req.session.username}, function (err, friendlist) {
async.each(friendlist.friends, function(friend, callback) {
OnlineUser.findOne({userName: friend}, function (err, onlineFriend) {
if (onlineFriend != null) {
onlinefriends.push(onlineFriend.userName);
console.log("a loop");
}
callback();
});
}, function(err) {
console.log("online friends: " + onlinefriends);
console.log("redirecting");
res.render('index', { // this is still inside the forEach function
friendlist: friendlist.friends,
onlinefriendlist: onlinefriends,
username: req.session.username
});
});
});
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
17786 次 |
| 最近记录: |