使用node.js mongodb
本机模块我试图使用一个promisified迭代器,但它不会在解雇finalCallback
db.collection('items').find({}).forEach(promiseIterator, finalCallback);
function promiseIterator(doc){
return Promise.resolve(doc)
.then(res => {
console.log(res); // this fires *after* finalCallback fires
})
}
function finalCallback(res){
console.log(res); // this fires *before* promiseIterator resolves all promise chains
}
文档在这里:https://mongodb.github.io/node-mongodb-native/2.2/api/Cursor.html#~resultCallback
他们的ES6示例都使用生成器,所以我不确定Promise是否在这里工作。但在解雇finalCallback
之前,承诺链尚未完全解决。
https://mongodb.github.io/node-mongodb-native/2.2/reference/ecmascript6/crud/
我遇到此问题的原因是因为我的promiseIterator
需要对每个文档进行多次异步/默认调用。 (我无法使用.toArray()
将所有文档加载到内存中,因为有超过一百万个文档,并且在尝试时出现process out of memory
错误。
答案 0 :(得分:1)
不幸的是你做不到。 Mongodb原生的forEach并不等待Promise如您所注意到的那样解决。他们只是调用回调函数并继续下一个对象。
光标的forEach
源代码(第769行)
http://mongodb.github.io/node-mongodb-native/2.2/api/lib_cursor.js.html
您需要使用next
和hasNext
手动迭代。
http://mongodb.github.io/node-mongodb-native/2.2/api/Cursor.html#next
编辑:添加了示例。
您可以完全按照jstice4all成功使用promises。这是他的例子,有更多细节。
db.collection('items').find({}, (err, resultCursor) => {
resultCursor.next(processItem);
function processItem(err, item) {
if(item === null) return; // All done!
// Add your asynchronous function/chain of functions in place of Promise.resolve()
Promise.resolve().then(() => {
resultCursor.next(processItem); // Read next item from database
});
}
});
当然,这会一个接一个地连续处理所有对象。如果你想并行处理所有对象并在做其他事情之前等待它们完成,你应该使用Promise.all
收集所有创建的promises。
顺便说一句。不推荐使用nextObject
,因此您可以使用next
代替它。
答案 1 :(得分:1)
您可以使用nextObject
代替forEach
的递归:
db.collection('items').find({}, function(err, resultCursor) {
function processItem(err, item) {
if(item === null) {
return; // All done!
}
externalAsyncFunction(item, function(err) {
resultCursor.nextObject(processItem);
});
}
resultCursor.nextObject(processItem);
}