【问题标题】:Using Promise.all on Firestore query在 Firestore 查询中使用 Promise.all
【发布时间】:2018-04-23 05:26:03
【问题描述】:

我有一个 HTTP Cloud 函数,可以查询和更新 Firestore 中的文档。基本上,该函数的作用是从集合中选择所有车辆,计算不同时间范围(24 小时、12 小时和 6 小时)的每辆车的能源使用量,汇总结果并使用结果更新另一个集合。

这就是我的 Firestore 的结构。

vehicles (collection)
----vehicle (document)
    -----telemetry (subcollection) this is where the energy values will come from

到目前为止,这是我的脚本,我使用 Promise.all 来组合不同时间范围的所有查询,计算每辆车的能源使用量并将其加到运行总数中,但这并不好用。

exports.getAllEnergyUsage = functions.https.onRequest((req, res) => {

  const store = admin.firestore()
  store.collection('vehicles').get().then(snapshot => {

    let allYesterdayResult = 0;
    let allTwelveHourResult = 0;
    let allSixHourResult = 0;

    snapshot.forEach(doc => {
      const data_dict = doc.data();
      let queryResults = [];
      const vehicle = data_dict.vehicle_name;
      const vehicleRef = store.collection('vehicles').doc(vehicle);
      const today = new Date();
      const yesterday = new Date(today.getTime() - (24*60*60*1000));
      const twelveHours = new Date(today.getTime() - (12*60*60*1000));
      const sixHours = new Date(today.getTime() - (6*60*60*1000));

      // console.log(today, sixHours);

      var queries = [
        vehicleRef.collection('telemetry').where('time_stamp', '<', today).where('time_stamp', '>', yesterday).get(),
        vehicleRef.collection('telemetry').where('time_stamp', '<', today).where('time_stamp', '>', twelveHours).get(),
        vehicleRef.collection('telemetry').where('time_stamp', '<', today).where('time_stamp', '>', sixHours).get()
      ]

      for (var i = 0; i < queries.length; i++) {
        queryResults.push(
          queries[i]
        )
      }

      Promise.all(queryResults)
        .then(snapShot=> {

          const yesterdayResult = result => getEnergy(result);
          const twelveHourResult = result => getEnergy(result);
          const sixHourResult = result => getEnergy(result);

          allYesterdayResult += yesterdayResult(snapShot[0])
          allTwelveHourResult += twelveHourResult(snapShot[1])
          allSixHourResult +=sixHourResult(snapShot[2])


          console.log("Done updating vehicle ", vehicle)
          // return res.send({"Result" : "Successful!"})
        }).catch(reason => {
          console.log(reason)
          // return res.send({"Result" : "Error!"})
      });



    })
    var vehicle_summary = {
      yesterday : allYesterdayResult,
      twelveHourResult : allTwelveHourResult,
      sixHourResult : allSixHourResult,
      timestamp : FieldValue.serverTimestamp()

    }
    console.log(vehicle_summary);
    store.collection('vehicles_summary').doc('energy').set(vehicle_summary);
  })

return res.send({"Result" : "Successful!"})


});

这是结果,这不会给我我想要的能源使用摘要,因为据我了解,承诺仍在运行,但函数已经返回(如果我错了,请纠正我)。

RESPONSE RECEIVED FROM FUNCTION: 200, {"Result":"Successful!"}
info: { yesterday: 0,
  twelveHourResult: 0,
  sixHourResult: 0,
  timestamp: FieldValue {} }
info: Running loop on each SnapShot=======
info: Running loop on each SnapShot=======
Running loop on each SnapShot=======
Done updating vehicle  Vehicle2
Running loop on each SnapShot=======
Running loop on each SnapShot=======
info: Running loop on each SnapShot=======
Done updating vehicle  Vehicle1
info: Running loop on each SnapShot=======
info: Running loop on each SnapShot=======
Running loop on each SnapShot=======
info: Done updating vehicle  Vehicle3

知道如何实现这一点吗?我来自 Python,刚刚学习 node.js,我仍然非常同步地思考。

【问题讨论】:

    标签: node.js firebase google-cloud-firestore google-cloud-functions es6-promise


    【解决方案1】:

    您在任何异步工作完成之前返回结果:

    return res.send({"Result" : "Successful!"})
    

    发送此响应后,此函数将终止。无法保证在此之后的任何异步工作都会按您预期的方式完成。

    对于 HTTP 函数,您应该在所有异步工作完全完成后发送响应。

    【讨论】:

    • 如何判断所有异步工作是否完成?从我的代码中,对于每个文档,我都在运行 Promise.all。
    • 是的,你需要一个代表所有工作的promise。将它们全部收集到一个数组中,并在整个列表中使用 Promise.all。再说一遍:您目前实际上并没有等到任何工作完成后才返回响应。试着简化你的工作,先把它做好,然后让它复杂化以满足全部要求。
    • 将所有查询放在一个承诺中的问题。是我不知道如何确定哪个查询是 24,12 或 6 小时。因为我必须根据这些时间范围总结结果。而promise.all 据我所知只接受数组,如果我可以使用对象并将其传递给promise.all 这样会很好。{"24_h":query, "12_h":query, "6_h":query} 所以当promise.all 完成时,我可以参考确定时间范围。
    • @essramos Promise.all 将按照添加到数组中的相同顺序返回已解析的查询
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-06
    • 1970-01-01
    • 1970-01-01
    • 2019-03-17
    • 2020-11-22
    • 2021-07-29
    相关资源
    最近更新 更多