如何使用光标映射/ forEach与异步内部函数?

问题描述 投票:1回答:2

我正在尝试对查找结果中的每个文档执行异步操作。有没有办法使用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。

javascript node.js mongodb
2个回答
1
投票

你可以使用.map,但你需要将每个异步调用映射到Promise。然后,您可以在结果上调用Promise.all,这将解析传递的数组中的所有Promise何时解析。

在异步函数中没有任何意义,立即return awaits的东西 - 它已经是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

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(...)与promises一起使用,因为它的实现并不等待每个promise在转到光标的下一个条目之前得到解决。

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

© www.soinside.com 2019 - 2024. All rights reserved.