Узел | Обещание не заканчивается

#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 не является узким местом. Время до последнего журнала коллекции меня устраивает. Но потом это застревает.