【问题标题】:Async/await to lookup document IDs and then look up separate document set异步/等待查找文档 ID,然后查找单独的文档集
【发布时间】:2019-09-12 03:11:45
【问题描述】:

我在我的应用中记录了用户“喜爱”的最喜欢的优惠。这些记录包括所有者和商品 ID。我想为特定用户收集前 25 个最喜欢的优惠。所有的 firestore 命令都是异步的,我需要在渲染页面之前收集所有的 offer 对象。

这是我第一次使用 async/await,从一开始就迅速成长为嵌套的 async/await。必须有一种更简单的方法来从 fav 对象中收集 ID,然后使用这些 ID 查找 Offer?

        async getItems() {
          const collectfavs = async () => {
            favsRef = firestore.collection('favs').where('owner','==',getUserID()).orderBy('created', 'desc').limit(25);
            let allFavsSnapshot = await favsRef.get();
            allFavsSnapshot.forEach(doc => {
                let data = doc.data();
                favsList.push(data.offer);
            });
            console.log('favs:',favsList);
          }
          const collectoffers = async () => {
            favsList.forEach(async (fav) => {
                let doc = await firestore.collection('offers').doc(fav).get()
                console.log('doc:', doc);

                let data = doc.data();
                data.id = doc.id;
                offerList.push(data);
            });
            console.log('offers:', offerList);
          }
          await collectfavs();
          await collectoffers();
       }

【问题讨论】:

    标签: javascript firebase google-cloud-platform google-cloud-firestore


    【解决方案1】:

    我不确定您为什么定义两个本地函数只是为了调用它们一次。这似乎比完成工作所需的代码更多。除此之外,你所做的对我来说似乎并不复杂。但是如果你想减少代码行数:

        async getItems() {
            favsRef = firestore.collection('favs').where('owner','==',getUserID()).orderBy('created', 'desc').limit(25);
            let allFavsSnapshot = await favsRef.get();
            allFavsSnapshot.forEach(doc => {
                let data = doc.data();
                favsList.push(data.offer);
            });
            console.log('favs:',favsList);
    
            favsList.forEach(async (fav) => {
                let doc = await firestore.collection('offers').doc(fav).get()
                console.log('doc:', doc);
    
                let data = doc.data();
                data.id = doc.id;
                offerList.push(data);
            });
            console.log('offers:', offerList);
       }
    

    请记住,我不知道您在哪里定义了 favsListofferList,所以我只是按照您展示的方式盲目使用它。

    【讨论】:

    • 您的解决方案将 favs、offers、doc、doc 打印到控制台...这意味着当我在页面上使用 offerList 时它是空的,而不是预先填充。
    • 我添加了解决方案,即编写自己的 asyncForEach 以等待每个 Firebase 承诺完成。棘手。
    【解决方案2】:

    从您对 Doug Stevenson 的评论中了解到,您希望确保在使用它们之前填写​​您的列表。为了做到这一点,你可以Promises。 Promises 所做的是为我们提供了一种以顺序方式处理代码中的异步的方法。

    您需要做的就是创建一个承诺,以确保您首先填写所需的列表,然后使用它们。

    如果这有帮助,请告诉我。

    【讨论】:

    • Firebase 似乎经常使用 Promise,因为每次调用都是异步的。当我嵌套各种 firebase/firestore 函数以添加或更新数据存储对象时,这会有所帮助。似乎在 JS 中人们更倾向于使用 async/await 来处理异步调用。在这种情况下,我想在呈现页面之前使用 async/await 来收集数据存储对象的列表。
    【解决方案3】:

    我最终需要创建自己的 asyncForEach 例程,以适应循环内对 firebase 的异步调用。感谢塞巴斯蒂安肖邦的一篇文章asyncForEach

    async function asyncForEach(array, callback) {
      for (let index = 0; index < array.length; index++) {
        await callback(array[index], index, array);
      }
    }
    

    然后在我的 getItems 中:

    await asyncForEach(favsList, async (fav) => {
            let doc = await firestore.collection('offers').doc(fav).get()
            let data = doc.data();
            data.id = doc.id;
            offerList.push(data);
        });
    

    【讨论】:

      猜你喜欢
      • 2021-02-27
      • 2020-09-15
      • 1970-01-01
      • 2017-11-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-11
      • 1970-01-01
      相关资源
      最近更新 更多