【问题标题】:How to loop async query code of firebase?如何循环firebase的异步查询代码?
【发布时间】:2019-08-24 22:44:03
【问题描述】:

我正在尝试循环并从 firestore 获取不同的文档。正如您在下面的代码中看到的那样,“文档 ID”由名为“cart”的数组提供。

我尝试过的编程逻辑是这样的,每次迭代中的while循环从firestore获取文档,在第一个“then”部分它保存它刚刚获得的数据,在第二个“then”它增加“i” ' 并执行下一个循环。

问题是 while 循环不等待该 get 请求完成。它只是不断循环和崩溃。

即使我以某种方式设法正确执行循环部分也是如此。我将如何管理程序的整体执行流程,以便只有在完成循环部分之后才会执行进一步的代码,因为下面的代码使用循环部分更新的购物车数组。

let i = 0
while (i < cart.length) {
    let element = cart[i]
    db.collection(`products`).doc(element.productID).get().then((doc1) => {
        element.mrp = doc1.data().mrp
        element.ourPrice = doc1.data().ourPrice
        return console.log('added price details')
    }).then(() => {
        i++;
        return console.log(i)
    }).catch((error) => {
        // Re-throwing the error as an HttpsError so that the client gets the error details.
        throw new functions.https.HttpsError('unknown', error.message, error);
    });
}
return db.collection(`Users`).doc(`${uid}`).update({
    orderHistory: admin.firestore.FieldValue.arrayUnion({
        cart,
        status: 'Placed',
        orderPlacedTimestamp: timestamp,
        outForDeliveryTimestamp: '',
        deliveredTimestamp: ''
    })
}).then(() => {
    console.log("Order Placed Successfully");
})

【问题讨论】:

    标签: javascript firebase asynchronous promise google-cloud-firestore


    【解决方案1】:

    您的问题不是关于firebase,而是关于异步循环。你可以看到一些promises的例子hereasync/awaithere

    你可以在 Promise 上使用 reduce。 请注意,所有的 Promise 都是同时创建的,但是对服务器的调用是一个接一个地完成的。

    cart.reduce(
      (promise, element) =>
        promise.then(() => {
          return db.collection(`products`)
            .doc(element.productID)
            .get()
            .then(doc1 => {
              element.mrp = doc1.data().mrp;
              element.ourPrice = doc1.data().ourPrice;
            });
        }),
      Promise.resolve()
    );
    

    如果可以,请改用async/await。在这里,所有的承诺一个接一个地被创建。

    async function fetchCart() {
      for (const element of cart) {
        const doc1 = await db.collection(`products`).doc(element.productID);
        element.mrp = doc1.data().mrp;
        element.ourPrice = doc1.data().ourPrice;
        console.log('added price details');
      }
    }
    

    【讨论】:

      【解决方案2】:

      对 Cloud Firestore 的每次调用都是异步发生的。因此,您的 while 循环会触发多个此类请求,但不会等待它们完成。

      如果您的代码需要所有结果,则需要使用 Promises 来确保流程。你已经在while 循环中使用了promise 来获取doc1.data().mrp。如果cart 是一个数组,您可以执行以下操作来收集数据加载时间的所有承诺:

      var promises = cart.map(function(element) {
         return db.collection(`products`).doc(element.productID).get().then((doc1) => {
              return doc1.data();
          });
      });
      

      现在您可以等待所有数据:

      Promise.all(promises).then(function(datas) {
        datas.forEach(function(data) {
          console.log(data.mrp, data.ourPrice);
        });
      });
      

      如果您在现代环境中,可以使用async/await 抽象出then

      datas = away Promise.all(promises);
      datas.forEach(function(data) {
        console.log(data.mrp, data.ourPrice);
      });
      

      【讨论】:

        猜你喜欢
        • 2015-04-01
        • 2018-03-06
        • 1970-01-01
        • 1970-01-01
        • 2019-03-12
        • 2021-02-03
        • 2018-10-17
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多