MongoDB和Node js异步编程
MongoDB and Node js Asynchronous programming
我正在尝试解决考试问题,因此无法按原样发布考试代码。 因此,我进行了简化,以便解决我不理解的核心概念。 基本上,我不知道如何减慢节点的异步执行速度,以便我的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);
});
我并不是说这是在Mongo中处理此特定问题的最佳方法,但是如果您需要等待数据库回复才能继续,那么只需使用回调即可启动下一个请求。
这起初并不明显,但您可以参考函数本身内部的结果处理函数:
var i = 0;
var mycback = function(err, doc_album) {
// ... process i-th result ...
if (++i < 100000) {
db.collections("album").findOne({'images': i}, mycback);
} else {
// request is complete, "return" result
result_cback(null, res);
}
};
db.collections('album').findOne({'images': 0}, mycback);
这也意味着你的函数本身将是异步的(即希望一个result_cback
参数与结果一起调用,而不是使用 return
)。
编写调用异步函数的同步函数是不可能的。
你不能在Javascript中"等待"一个事件...必须为结果设置处理程序,然后终止。
等待事件是通过编写"嵌套事件循环"在基于事件的处理中完成的,例如,这是大多数 GUI 框架中处理消息框的方式。这是Javascript设计者不想提供给程序员的功能(虽然不知道为什么)。
因为你知道它不会等待呼叫回来。您可以在回调函数中执行console.dir
,这应该可以工作(尽管我还没有测试过)
db.collection('albums').findOne(query, function(err, doc_album) {
if(err) throw err;
if (doc_album === null) {
orphans.push(i);
}
console.dir(orphans.length);
});
你不需要放慢任何速度。如果您只是尝试从相册集合中加载 100,000 张图像,则可以考虑使用异步框架。这将允许您分配任务,直到作业完成。
此外,您可能不希望逐个请求 100,000 条记录。相反,您可能希望对它们进行分页。
- 节点.js:如何以编程方式确定异步
- 异步编程-如何在对象数组中循环,并使用从api获取的数据更改每个对象的属性
- 从java脚本到C#的回调,C#和java脚本之间的异步编程
- JavaScript 异步编程:承诺与生成器
- 节点,异步编程,回调地狱
- 以编程方式将同步代码转换为异步代码
- MongoDB和Node js异步编程
- 如何在javascript中实现异步编程(promise)?是't javascript是一个ui线程环境
- JavaScript异步编程
- 使用Ramda处理异步编程
- 应该'Node.js中的异步编程会导致StackOverflow
- node.js中的异步编程是否会加快cpu密集型任务的速度?
- Node.js和异步编程回文
- 你需要知道的关于异步JS编程
- Nodejs异步编程——为什么有“async"模块需要吗?什么是“回调地狱”/“末日金字塔”
- 同步和异步编程(在node.js中)的区别是什么?
- 作为对象的回调——它与JavaScript中的异步编程的关系
- NodeJs 异步编程 - 协调并行调用
- Node.js和异步编程
- javascript中的异步编程