【问题标题】:Pass an object argument to Promise.all将对象参数传递给 Promise.all
【发布时间】:2018-04-24 17:10:47
【问题描述】:

我有三个基于时间范围的 Firestore 查询。 (24、12 和 6 小时)。我正在使用Promise.all,它可以工作。从代码中可以看出,我通过使用返回快照的索引来访问每个查询的结果。我已经读过返回值将按照 Promises 传递的顺序排列,而不管完成顺序如何。

现在,我希望能够将一个对象传递给Promise.all,因为我的查询数量对于我想要做的事情是不可预测的,基本上,我将循环到许多车辆并构建相同的 3对每个查询,我会将其全部传递给Promise.all。当Promise.all 返回时,我希望能够知道该快照所针对的车辆和时间范围。

因此,我想将此参数传递给Promise.all,而不是数组。

{"vehicle1_24":query, "vehicle1_12":query, "vehicle1_6":query,
"vehicle2_24":query, "vehicle2_12":query, "vehicle2_6":query}

代码

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!"})

【问题讨论】:

  • Promise.all() 需要一个数组。如果你想等待一堆都是对象属性的 Promise,那么你必须从对象中提取所有这些 Promise 并将它们放入一个数组中,这样你就可以使用该数组调用 Promise.all()。如果需要,您可以创建一个函数 Promise.allObject() 为您执行此操作。
  • 仅供参考,Bluebird promise libraryPromise.props(),听起来它可以满足您的需求。
  • 创建我自己的allObject() 是什么意思? @jfriend00
  • 我的意思是您创建自己的函数来执行您的要求。这将是一个函数,它从对象的属性中提取承诺,将它们放入数组中,对它们全部调用 Promise.all(),当 Promise.all() 解析时,它会根据需要处理结果并将其作为解析后的值返回。只需制作自己的函数来接受您要传入的对象,然后将数据转换为正确的形式以使用Promise.all(),因为您无法将对象直接传递给Promise.all()

标签: node.js firebase google-cloud-firestore


【解决方案1】:

本机不存在此功能,但应该相当容易编写,类似于

async function promiseAllObject(obj) {
  // Convert the object into an array of Promise<{ key: ..., value: ... }>
  const keyValuePromisePairs = Object.entries(obj).map(([key, valuePromise]) =>
    valuePromise.then(value => ({ key, value }))
  );

  // Awaits on all the promises, getting an array of { key: ..., value: ... }
  const keyValuePairs = await Promise.all(keyValuePromisePairs);

  // Turn it back into an object.
  return keyValuePairs.reduce(
    (result, { key, value }) => ({ ...result, [key]: value }),
    {}
  );
}

promiseAllObject({ foo: Promise.resolve(42), bar: Promise.resolve(true) })
  .then(console.log); // { foo: 42, bar: true }

【讨论】:

    【解决方案2】:

    您可以使用以下代码将您的对象转换为您将传递给 Promise.all() 的数组

    var queriesObject = {"vehicle1_24":query, "vehicle1_12":query, "vehicle1_6":query, "vehicle2_24":query, "vehicle2_12":query, "vehicle2_6":query};
    //Of course, queriesObject can be an oject with any number of elements 
    
    
    var queries = [];
    
    for (var key in queriesObject) {
        if (queriesObject.hasOwnProperty(key)) {
            queries.push(queriesObject[key]);
        }
    }
    
    Promise.all(queries);
    

    您将在一个数组中收到 Promise.all 的结果,该数组对应于查询数组以相同顺序,请参阅:Promise.all: Order of resolved valueshttps://www.w3.org/2001/tag/doc/promises-guide#aggregating-promises

    【讨论】:

    • @essramos 你必须将一个可迭代对象传递给 Promise.all(),参见 developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…medium.com/@ma7moudfelfel/…。您的对象不是这样的可迭代对象。这是 jfriend00 在他的评论中告诉你的。正如我在回答中详述的那样,将其转换为可迭代的一种简单方法是将其转换为数组。此外,我不明白为什么我被否决了:如果能以我改进自己的方式进行任何解释,我将不胜感激。
    • 我不确定你为什么被否决。但你的答案不是我需要的。我知道传递一个对象本身是不可能的,这就是为什么我要问一种方法如何做到这一点。不是如何将对象转换为数组。
    • @essramos 感谢您的回答。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-19
    • 2018-04-26
    相关资源
    最近更新 更多