【问题标题】:How to make asynchronous calls inside of a firestore .forEach loop?如何在 firestore .forEach 循环内进行异步调用?
【发布时间】:2021-02-05 00:55:29
【问题描述】:

我正在使用 firebase admin SDK 服务器端,并且在我的一条路线中,我获取了一个集合,然后循环遍历所述集合中的每个文档...在每次迭代期间,我使用一个属性值来执行第二次得到()。在第二次 get() 的 then() 中,我再次使用初始 get 中的数据来制作最终的第三次 get()。

不幸的是,这些嵌套调用的异步特性似乎会产生不良结果。

这里是路由函数:

router.get('/list', authorization, (req, res) => {
  console.log('/reports/list entered...')

  admin
    .firestore()
    .collection('user-reports')
    .get()
    .then(querySnapshot => {
      const reports = []
      querySnapshot.forEach(snapshotDocument => {
        const closed = snapshotDocument.get('closed')
        console.log(`closed status: ${closed}`)

        if (closed === false) {
          const data = snapshotDocument.data()
          console.log(`condition passed, data: ${JSON.stringify(data)}`)
          // get # of reports made by sender
          admin
            .firestore()
            .collection('users')
            .doc(data.reportee)
            .get()
            .then(doc => {
              data['reportee'] = {
                reportActivity: doc.get('reportActivity')
              }
              console.log(`first then => data; ${JSON.stringify(data)}`)
              // get report history of reportee
             
              admin
                .firestore()
                .collection('users')
                .doc(data.reporter)
                .get()
                .then(doc => {
                  data['reporter'] = {
                    reportActivity: doc.get('reportActivity')
                  }
                  console.log(`second then, ${JSON.stringify(data)}`)
                  reports.push(data)
                })
                .catch(err => {
                  return res.json({ error: true, message: err })
                })
            })
            .catch(err => {
              return res.json({ error: true, message: err })
            })
        }
      })
      console.log(`pre-response: ${JSON.stringify(reports)}`)
      return res.json({ reports })
    })
    .catch(err => res.json({ error: true, message: err }))
})

即时记录的是“第一个条件通过”、“预响应:[]”和“首先然后 => 数据”。当我最终返回“报告”时,它是空的。有没有更有效的方法在 foreach 循环中运行 firestore 方法?

【问题讨论】:

    标签: reactjs firebase google-cloud-firestore


    【解决方案1】:

    解决方案几乎总是使用Promise.all() 等待一堆promise 解决:

      rturn Promise.all(querySnapshot.map(snapshotDocument => {
        const closed = snapshotDocument.get('closed')
        console.log(`closed status: ${closed}`)
    
        if (closed === false) {
          const data = snapshotDocument.data()
          console.log(`condition passed, data: ${JSON.stringify(data)}`)
          // get # of reports made by sender
          return admin
            .firestore()
            .collection('users')
            .doc(data.reportee)
            .get()
            .then(doc => {
              data['reportee'] = {
                reportActivity: doc.get('reportActivity')
              }
              console.log(`first then => data; ${JSON.stringify(data)}`)
              // get report history of reportee
             
              return admin
                .firestore()
                .collection('users')
                .doc(data.reporter)
                .get()
                .then(doc => {
                  data['reporter'] = {
                    reportActivity: doc.get('reportActivity')
                  }
                  console.log(`second then, ${JSON.stringify(data)}`)
                  return data;
                })
                .catch(err => {
                  return res.json({ error: true, message: err })
                })
            })
            .catch(err => {
              return res.json({ error: true, message: err })
            })
        }
      })
      .then((reports) => {
        console.log(`pre-response: ${JSON.stringify(reports)}`)
        return res.json({ reports })
      })
    

    可能有一些语法错误,但基本的变化:

    1. 使用querySnapshot.map(snapshotDocument => { 将文档转换为承诺/结果列表。
    2. 使用Promise.all 创建一个promise,当所有这些结果都完成后解决。
    3. 根据需要从最深处一直到主代码返回结果。

    请注意,您在这里所做的承诺嵌套是不寻常的并且是反模式的,因此建议您还研究学习链接承诺(这样您最终会得到一个 catch - 而不是全部使用它们这个地方。

    【讨论】:

      猜你喜欢
      • 2013-09-27
      • 1970-01-01
      • 2019-03-24
      • 2019-01-29
      • 2017-05-16
      • 2018-08-22
      • 1970-01-01
      • 2021-12-12
      • 1970-01-01
      相关资源
      最近更新 更多