Функция asyn c возвращает Promise <Pending> - PullRequest
0 голосов
/ 29 марта 2020

Я создаю грубое приложение для проекта, люди могут добавлять просмотр и удалять записи, я использую nodejs, js и fireabse для этого. у меня есть такая структура базы данных firestore:

entries:
   --entry id
      --entry data
users:
   --user id
      --user email (query)
      -- my entries (collection)
           -- entries id
              --entry id 

Теперь я хочу отобразить все записи пользователей, поэтому я создал эту функцию module.exports:

module.exports = {  
  //get all the users entries from database with passed in uid ('/dashboard')
  getUserEntries: async uid => {
    //get all his entries docs id from "myEntries" collection in an, array
    const usersEntriesId = await db
      .collection("users")
      .doc(uid)
      .collection("myEntries")
      .get()
      .then(entries => {
        return entries.docs.map(entry => entry.data().entry);
      })
      .catch(err => console.log(err));
    console.log(usersEntriesId); //works fine, logs array with ids

    const userEntriesDocs = usersEntriesId.map(async id => {
      const entry = await db
        .collection("entries")
        .doc(id)
        .get()
        .then(entry => {
          return entry.data();
        });
      console.log("hello:", entry); //works fine returns logs entry data

      return entry;
    });

    console.log("hello1: ", userEntriesDocs); //doesnt work i get "hello1:  [ Promise { <pending> },
 // Promise { <pending> },
  //Promise { <pending> } ]"
//i got three entries, that's why i get 3 times "Promise { <pending> }"
  }
};

, так как мне решить, что ?

Спасибо

1 Ответ

2 голосов
/ 29 марта 2020

ну, async функция возвращает Promise, это как они работают под капотом. Если бы не было .map, вы могли бы просто await использовать эту функцию или использовать ее как произвольно Promise с .then() и .catch. Но поскольку существует массив Promise, вам нужно Promise.all, чтобы дождаться разрешения всех проблем.

const userEntriesDocs = await Promise.all(usersEntriesId.map(async id => {
....
);

Осторожно: в отличие от .allSettled, .all() немедленно потерпит неудачу, если произойдет сбой любого из следующих Promise. Поэтому, если по какой-либо причине вы хотите получить данные из тех запросов, которые были выполнены успешно, вам нужны более сложные логики c.

В качестве альтернативы вы можете go - l oop вручную:

const userEntriesDocs = [];
for(const docPromise of userEntriesId.map(.....)) {
  userEntriesDocs.push(await docPromise);
}

Но мне await Promise.all[...] более читабельно.

Также я подчеркиваю, есть массив Обещаний (запросы уже отправлены). Если вы попытаетесь отправить запросы внутри l oop, например

const userEntriesDocs = [];
for(const id of userEntriesId) {
  userEntriesDocs.push(await db
        .collection("entries")
        .doc(id)
        .get()
        .then(entry => {
          return entry.data();
         })
  );
}

, вы обнаружите, что запросы выполняются строго один за другим, а не параллельно. Это потребует гораздо больше времени для обработки списка.

...