gpt4 book ai didi

javascript - 在 NodeJS MongoDB 中保留嵌套 for 循环和回调中的执行顺序

转载 作者:行者123 更新时间:2023-12-03 12:36:05 25 4
gpt4 key购买 nike

Scenario: There are users and users has many posts. For a particular group of users, I need to fetch 10 recent posts per user and send them in response.
Here is what I have come up with:

users 是包含用户信息的数组。

var allPosts = [];

for(var i=0; i<users.length; i++){
(function(i){ //Level-1
db.collection('posts', function(err, postCollection){
(function(i){ //Level-2
postCollection.find({"user_id": users[i]['user_id']}).sort({"created": -1}).limit(10).toArray(function(err, post) {
(function(i){ //Level-3
for(var j =0; j< post.length; j++){
(function(j){
post[j]['created'] = ObjectId(post[j]['_id'].toString()).getTimestamp();
allPosts.push(post[j]);
if(j === post.length-1){
res.send(allPosts);
}
})(j);
}
})(i);
});
})(i);
});
})(i);
}

现在,执行顺序保留到 Level-2,但是当进入 Level-3 时,所有事情都会出错:我的数组中有两个用户,一个用户有 3 个帖子,另一个用户有 10 个帖子,有时会响应只有 3 个帖子,有时是全部 13 个帖子。我认为这是因为 MongoDB。我什至通过使用立即调用的函数表达式(IIFE)来处理执行顺序,但它在这里似乎不起作用。任何帮助表示赞赏。谢谢

最佳答案

首先你应该美化你的代码。在其他循环的回调内的循环内使用匿名函数并不容易维护或阅读。

您的代码的问题是,在最后一个循环( j 循环)中,您在其他用户的查询完成之前到达 j == users.length - 1 ,因此发送的响应中包含完成的发布查询数量,直到那一刻。

您犯的另一个大错误是您在循环内请求 post 集合。 这是错误的!您应该缓存数据库和集合。

试试这个代码:

var allPosts = [];
var post_collection = null;

var get_user = function(i, callback) {
post_collection
.find({"user_id": users[i]['user_id']})
.sort({"created": -1})
.limit(10)
.toArray(function(err, post) {

// Do something when you get error
// Always call the callback function if there is one
if(err) {
callback();
return;
}

for(var j=0; j<post.length; ++j) {
post[j]['created'] = ObjectId(post[j]['_id'].toString()).getTimestamp();
allPosts.push(post[j]);
}

callback();
});
};

var fetch_users = function() {
var count = users.length;

for(var i=0; i<users.length; ++i) {
get_user(i, function() {
// Each time a query for one user is done we decrement the counter
count--;

// When the counter is 0 we know that all queries have been done
if(count === 0) {
res.send(allPosts);
}
});
};
};

// Get the collection, check for errors and then cache it!
db.collection('posts', function(err, postCollection) {

// Always check for database errors
if(err) {
console.log(err);
return;
}

post_collection = postCollection;
fetch_users();
});

您应该知道此代码未经测试。我可能漏掉了一个分号或一些大括号,但你应该很容易就能弄清楚。

关于javascript - 在 NodeJS MongoDB 中保留嵌套 for 循环和回调中的执行顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23731480/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com