javascript - 异步函数返回 Promise <Pending>

标签 javascript node.js firebase promise async-await

我正在为一个项目构建一个 CRUD 应用程序, 人们可以添加查看和删除条目,我为此使用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> }"
  }
};

那么我该如何解决这个问题呢?

谢谢

最佳答案

嗯,async 函数返回 Promise,这就是它们在幕后的工作方式。如果没有 .map,您可以在该函数上 await 或将其用作任意 Promise.then().catch。但由于有 Promise 数组,您需要 Promise.all等到一切都解决了。

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

注意:与 .allSettled 不同,如果任何后续的 Promise 失败,.all() 将立即失败。因此,如果出于任何原因您希望从成功的请求中获取数据,则需要更复杂的逻辑。

作为替代方案,您可以手动执行循环:

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

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

我还强调有一系列的 promise (请求已经发送)。如果您尝试在循环内发送请求,例如

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

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

关于javascript - 异步函数返回 Promise <Pending>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60907266/

相关文章:

javascript - 如何用JavaScript来摇动页面

javascript - 如何为不同的选择器重复一个功能?

ios - FIR 数据库查询 : how to do an inner join

javascript - TypeError : value. push is not a function with Angularjs $resource 查询

javascript - 如何删除除第一个之外的所有 URL 哈希值?

javascript - Node.js 上的 Access-Control-Allow-Origin 没有 Express.js

node.js - 可以使用 apache 在 nodejs 服务器之间进行负载平衡

node.js - 使用 TypeScript 配置 React Native 时出错

java - 无法将 java.lang.String 类型的对象转换为 com.rafaquarta.whatsapp.model.Usuario 类型

firebase - 当 Internet 连接恢复时,Firestore 不会立即开始监听更改