Как использовать карту курсора / forEach с асинхронной внутренней функцией? - PullRequest
0 голосов
/ 18 сентября 2018

Я пытаюсь выполнить асинхронную операцию для каждого документа в результате поиска. Есть ли способ использовать 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 голосов
/ 18 сентября 2018

Я полагаю, что вы могли бы использовать метод 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(...) с обещаниями, поскольку его реализация не 't ждать, пока каждое обещание будет выполнено, прежде чем перейти к следующей записи курсора.

Это основано на взгляде на реализацию Cursor в API драйвера MongoDB для узла здесь

0 голосов
/ 18 сентября 2018

Вы можете использовать .map, но вам нужно сопоставить каждый асинхронный вызов с Promise. Затем вы можете вызвать Promise.all для результата, который разрешится, когда все Обещания в переданном массиве разрешатся.

Нет смысла в асинхронной функции, которая сразу 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...