我正在组合async.queue
和Cursor.nextObject
来迭代游标并针对返回的文档执行一些异步工作。
已经有一个很棒的小程序包,https://www.npmjs.org/package/mongo-cursor-processing,但遗憾的是它并没有公开我需要的底层队列。
所以,我尝试自己实现它,但遇到了障碍。有时,Cursor.nextObject
会返回null
,实际上有更多文档。
这是我附加到队列中的一小段代码片段,用于说明:
if (this.cursor && this.length() < this.concurrency) {
this.cursor.nextObject(function(err, item) {
console.log(this.name + ': ' + (item ? item._id : '<null>') + ' ' + (err ? err : '<null>'));
if (item) {
this.push(item);
} else {
// delete this.cursor;
}
}.bind(this));
}
控制台日志显示:
... Maybe 100 lines ...
prop-queue: 511abbd59c0d972a3e000119 <none>
prop-queue: 511abbd59c0d972a3e00011d <none>
prop-queue: 511abbd59c0d972a3e000120 <none>
prop-queue: 511abbd59c0d972a3e000122 <none>
prop-queue: <none> <none>
prop-queue: 511abbd59c0d972a3e000125 <none>
prop-queue: 511abbd59c0d972a3e000127 <none>
prop-queue: 511abbd59c0d972a3e000129 <none>
prop-queue: 511abbd59c0d972a3e00012c <none>
... 1000's more lines before the next null ...
有时,<none> <none>
行会在下一次调用成功之前重复两次。
真正有趣的部分是当我在Mongo shell中执行查询时,在511abbd59c0d972a3e000122
和511abbd59c0d972a3e000125
打印到控制台之间会有暂停。暂停持续大约0.75秒,并且正好在光标中命中空文档的位置。我在查询中迭代了数千个文档,这是我遇到的唯一停顿。此外,检查空值两侧的两个文件没有显示出特殊性。
任何可能导致两种可能相关现象的想法?
答案 0 :(得分:1)
我仍然不确定是什么导致暂停,但似乎这是罪魁祸首。
在暂停期间,Cursor.nextObject
在第一次返回之前被多次调用。其中一些调用正在返回null
。解决方案是确保永远不会同时调用Cursor.nextObject
。
if (this.cursor && !this.cursor_exec && this.length() < this.concurrency) {
this.cursor_exec = true;
this.cursor.nextObject(function(err, item) {
console.log(this.name + ': ' + (item ? item._id : null) + ' ' + (err ? err : null));
this.cursor_exec = false;
if (item) {
this.push(item);
} else {
delete this.cursor;
}
}.bind(this));
}