#javascript #node.js #typescript #mongodb #es6-promise
Вопрос:
Я пытаюсь извлечь данные из разных коллекций из MongoDB. Я делаю это с Node.js и обещания. Вот несколько основных кодов:
await Promise.all( ["a", "b", "c"].map(async (collection) =gt; { const query: any = { "_id": { $in: ids} } // I just use toArray for demonstration purposes const data = await this.db!.collection(collection).find(query).toArray() for (let i = 0; i lt; data.length; i ) { const document = data[i] // Do something... } console.log(collection) return true }) ) console.log("done")
Я делаю это для восьми коллекций (a, b, …, h). Данные извлекаются из базы данных и обрабатываются правильно в приемлемые сроки. Затем он печатает название для каждой коллекции. Но это не продолжается. Это не завершает обещание и не переходит в журнал выполненных действий.
Метод вызывается в задаче JS-Worker. В чем здесь может быть проблема? У меня еще никогда не было проблем с обещаниями и большим объемом данных.
Комментарии:
1. Что происходит, когда вы утешаете. зарегистрируйте обещание ожидания.все звонят? Кроме того, просто чтобы убедиться, что console.log («готово») находится в том же теле асинхронной функции, что и вызов Promise.all, верно?
2. @Xeelley
Promise.all
также принимает массив всего, что угодно..Promise.all([1,2,3,false,undefined]).then(console.log);
является допустимым кодом.3. @BrunoFarias хм, так что я был неправ, извините, я виноват, я удаляю свое предыдущее предложение
4. @BrunoFarias он печатает массив из восьми истинных элементов
Ответ №1:
На самом деле это синхронное выполнение. Он не перейдет в следующую коллекцию до тех пор, пока не будет завершен предыдущий вызов бд. Вместо этого функция со стрелкой должна возвращать обещание.
Решение состоит в том, чтобы изменить код таким образом-
async function callDb(collection) { const query: any = { "_id": { $in: ids} } // I just use toArray for demonstration purposes const data = await this.db!.collection(collection).find(query).toArray() for (let i = 0; i lt; data.length; i ) { const document = data[i] // Do something... } console.log(collection) return true } await Promise.all( ["a", "b", "c"].map(callDb) ) console.log("done")
Комментарии:
1. Я попробовал твое решение. Но я не думаю, что асинхронные функции называются синхронными. Если я сначала распечатаю коллекцию, то все выходные данные появятся одновременно. Кроме того, запрос MongoDB не является узким местом. Время до последнего журнала коллекции меня устраивает. Но потом это застревает.