如何使用带有异步内部函数的游标映射/ forEach?

时间:2018-09-18 03:00:18

标签: javascript node.js mongodb

我正在尝试对查找结果中的每个文档执行异步操作。有没有办法使用cursor.map或cursor.forEach?

我尝试了这两种方法,但是我没有任何运气。

# Using map
const x = await db.collection('collectionName').find({});
x.map(async doc => return await operation(doc));
// or
await x.map(async doc => return await operation(doc));

# Using forEach
const x = await db.collection('collectionName').find({});
x.forEach(async doc => await operation(doc));
// or
await x.forEach(async doc => return await operation(doc));

我知道我可以花点时间使它工作,例如:

const x = await db.collection('collectionName').find({});

while (await x.hasNext()) {
    const doc = await x.next();
    await operation(doc);
}

我的问题是,是否有可能完全使用map / forEach。

2 个答案:

答案 0 :(得分:1)

您可以使用.map,但需要将每个异步调用映射到Promise。然后,您可以对结果调用Promise.all,当传递的数组中的所有Promises解析时,该解析将解决。

异步功能没有任何意义可以立即return await进行操作-它已经是Promise,而await不会使您的代码在这种情况下更平坦或更易读。

因此,您可以使用:

const allPromises = x.map(operation);
const resultsOfOperations = await Promise.all(allPromises);
// resultsOfOperations will be an array with the resolved values

假设operation接受一个参数。否则,您必须显式地将每个doc传递给它,以避免将第二个和第三个参数设置为迭代索引和基本数组。

const allPromises = x.map(doc => operation(doc));
const resultsOfOperations = await Promise.all(allPromises);
// resultsOfOperations will be an array with the resolved values

答案 1 :(得分:0)

我相信您可以在Cursor.prototype.map()中使用Promise.all()方法,如下所示:

const x = await db.collection('collectionName').find({});
const promisesArray = x.map(doc => operation(doc));
const results = await Promise.all(promisesArray);

不幸的是,我不认为您可以将Cursor.prototype.forEach(...)与Promise一起使用,因为它的实现方式是在等待光标的下一个输入之前不等待每个Promise被解决。

这是基于对节点here的MongoDB驱动程序API中的Cursor实现的研究