我正在尝试解决考试问题,因此我无法按原样发布我的考试代码。所以我进行了简化,以解决我不理解的核心概念。基本上,我不知道如何减慢 Node 的异步执行速度,以便我的 mongo 代码可以跟上它。这是代码:
MongoClient.connect('mongodb://localhost:27017/somedb', function(err, db) {
if (err) throw err;
var orphans = [];
for (var i; i < 100000; i++) {
var query = { 'images' : i };
db.collection('albums').findOne(query, function(err, doc_album) {
if(err) throw err;
if (doc_album === null) {
orphans.push(i);
}
});
}
console.dir(orphans.length);
return db.close();
});
因此,我尝试创建一个由不符合我的查询条件的图像组成的数组。我最终得到的 orphans.length 值为 0,因为 Node 不会等待回调完成。如何修改代码,以便在计算数组中不符合查询条件的图像数量之前回调完成执行?
预先感谢您的宝贵时间。
巴拉特
最佳答案
我假设您想要执行 100000 次并行数据库调用。为了在每个调用回调中“等待”10000 个调用完成,我们增加完成的调用计数器,并在最后一个调用完成时调用主回调。请注意,这里最常见的错误是使用 for 循环变量作为回调内的闭包。这不会按预期工作,因为首先调度所有 10000 个处理程序,并且在第一个执行时循环变量具有相同的最大值。
function getOrphans(cb) {
MongoClient.connect('mongodb://localhost:27017/somedb', function(err, db) {
if (err) cb(err);
var orphans = [];
var numResponses = 0;
var maxIndex = 100000
for (var i = 0; i < maxIndex; i++) {
// problem: by the time you get reply "i" would be 100000.
// closure variable changed to function argument:
(function(index) {
var query = { 'images' : index };
db.collection('albums').findOne(query, function(err, doc_album) {
numResponses++;
if(err) cb(err);
if (doc_album === null) {
orphans.push(index);
}
if (numResponses == maxIndex) {
db.close();
cb(null, orphans);
}
});
})(i); // this is "immediately executed function
}
});
}
getOrphans(function(err, o) {
if (err)
return console.log('error:', err);
console.log(o.length);
});
关于javascript - MongoDB 和 Node js 异步编程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19043145/