Node.js 如何让cursor.forEach()迭代器等待承诺链解析?
使用node.jsNode.js 如何让cursor.forEach()迭代器等待承诺链解析?,node.js,mongodb,node-mongodb-native,Node.js,Mongodb,Node Mongodb Native,使用node.jsmongodbnative模块,我试图使用promisified迭代器,但在触发finalCallback db.collection('items').find({}).forEach(promiseIterator, finalCallback); function promiseIterator(doc){ return Promise.resolve(doc) .then(res => { console.log(
mongodb
native模块,我试图使用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
}
文件在这里:
他们的ES6示例都使用生成器,所以我不确定承诺在这里是否有效。但在启动finalCallback之前,承诺链还没有完全解决
出现此问题的原因是我的
promisediator
需要对每个文档进行几个异步/promisified调用。(我无法使用.toArray()将所有文档加载到内存中)
因为有超过一百万个文档,当我尝试这样做时,我遇到了一个内存不足的进程
错误。不幸的是,你不能。Mongodb native的forEach并没有像你所注意到的那样等待承诺的解决。它们只需要调用回调函数,然后继续下一个对象
光标的forEach
源代码(第769行)
您需要使用next
和hasNext
手动迭代
编辑:添加了示例
您可以完全按照jstice4all成功的方式使用承诺
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
顺便说一句,
nextObject
已被弃用,因此您可以使用next
代替它。不幸的是,您不能。Mongodb native的forEach不会像您所注意到的那样等待承诺的解决。它们只需调用回调函数并继续下一个对象
光标的forEach
源代码(第769行)
您需要使用next
和hasNext
手动迭代
编辑:添加了示例
您可以完全按照jstice4all成功的方式使用承诺
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
顺便说一句,
nextObject
已被弃用,因此您可以使用next
来代替它。您可以使用带有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);
}
您可以将递归与
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);
}
你能提供一个例子吗?我试图从他们的文档中使用
yield
,但我得到了一个语法错误。我使用的是node v7。他们的文档没有任何承诺示例(我只看到生成器),但他们声称你可以使用它们。externalAsyncFunction()在哪里
在您的示例中从调用?我的示例只是引用了jstice4all的示例,这似乎是正确的。与在Thia中复制示例相比,最好是引用该示例。我没有得到传递给externalAsyncFunction
的回调。我将jstice4all的示例与我的示例结合在一起。现在应该清楚了。您能提供示例吗?我尝试过了从他们的文档中使用yield
,但我得到一个语法错误。我使用的是节点v7。他们的文档没有任何承诺示例(我只看到生成器),但他们声称您可以使用它们。externalAsyncFunction()在哪里
在您的示例中从调用?我的示例只是引用了jstice4all的示例,这似乎是正确的。最好是引用该示例,而不是在thia中复制示例,因为我没有得到传递给externalAsyncFunction
的回调。我将jstice4all的示例与我的示例相结合。现在应该已经清楚了。是否可以使用h有nextObject
?是的,只需从然后
调用nextObject
。您介意添加一个使用承诺的示例吗.find()
和游标,而不是回调。我认为这是正确的答案,但我想使用承诺。这里可以将承诺与nextObject
一起使用吗?是的,只需从然后调用nextObject
。您介意添加一个将承诺与一起使用的示例吗。find()
和游标而不是回调。我认为这是正确的答案,但我想使用承诺。