异步函数返回Promise <Pending>

时间:2020-03-28 21:34:21

标签: javascript node.js firebase promise async-await

我正在为一个项目构建一个原始应用程序, 人们可以添加视图和删除条目,为此我正在使用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 个答案:

答案 0 :(得分:3)

好吧,async函数将返回Promise,说明它们是如何工作的。如果没有.map,则可以对该函数进行await或将其与Promise.then()一起用作任意.catch。但是由于存在Promise数组,因此您需要Promise.all等待所有问题解决。

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

当心:与.allSettled不同,.all()将在随后的Promise中任何一个失败时立即失败。因此,如果出于任何原因想要从成功的请求中获取数据,则需要更复杂的逻辑。

或者,您也可以手动循环:

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

但是对我来说await Promise.all[...]更具可读性。

我还要强调指出,这里有很多Promises(请求已经发送)。如果您尝试在循环内 发送请求,例如

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

您会发现请求严格按照一对一进行,而不是并行进行。这将需要更多时间来处理列表。