等待Firestore查询完成,然后返回云功能响应

时间:2019-06-25 09:28:36

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

我有一个云功能,可以在3个不同的集合中运行3个firestore查询。每个查询在then块内都有一个foreach循环,在foreach循环之后,它将在集合中执行更新。这是代码:

    const someDocRef
    const someDocRef2
    const someDocRef3

    db.collection("someOtherCollection").get().then(results=> {
       results.forEach(result=> {
          //do some work
       })
       someDocRef.update(....);
    })

    db.collection("someOtherCollection2").get().then(results=> {
       results.forEach(result=> {
          //do some work
       })
       someDocRef2.update(....);
    })

    db.collection("someOtherCollection3").get().then(results=> {
       results.forEach(result=> {
          //do some work
       })
       someDocRef3.update(....);
    })

    res.status(200).send("I waited for all the Queries AND the update operations inside the then blocks of queries to finish!");

那么所有操作完成后如何返回响应?

3 个答案:

答案 0 :(得分:1)

如果您在Cloud Function中调用某些异步Firestore方法(例如CollectionReference的{​​{3}}或DocumentReference的{​​{3}}),则只需要链接不同的promise这些方法返回的值。

因此,根据您的问题代码,您可以进行如下修改:

    const someDocRef
    const someDocRef2
    const someDocRef3

    db.collection("someOtherCollection").get()
    .then(results => {
       results.forEach(result=> {
          //do some work
       })
       return someDocRef.update(....);
    })
    .then(() => {    
       return db.collection("someOtherCollection2").get();
    })
    .then(results => {
       results.forEach(result=> {
          //do some work
       })
       return someDocRef2.update(....);
    })
    .then(() => {    
       return db.collection("someOtherCollection3").get();
    })
    .then(results => {
       results.forEach(result=> {
          //do some work
       })
       return someDocRef3.update(....);
    })
    .then(() => {    
       res.status(200).send("I waited for all the Queries AND the update operations inside the then blocks of queries to finish!");
    })    

请注意,这是可行的,因为someCollectionRefssomeDocRefs的数目是预先已知的。如果要执行可变数量的异步操作,则需要使用Promise.all()方法,如其他答案所示。


如果3个方块

    db.collection("someOtherCollectionX").get()
    .then(results => {
       results.forEach(result=> {
          //do some work
       })
       return someDocRefX.update(....);
    })

可以完全分开执行(即每个块的结果不会影响其他块),您可以按以下方式并行化调用:

    const someDocRef
    const someDocRef2
    const someDocRef3

    const p1 = db.collection("someOtherCollection").get()
    .then(results => {
       results.forEach(result=> {
          //do some work
       })
       return someDocRef.update(....);
    });

    const p2 = db.collection("someOtherCollection2").get()
    .then(results => {
       results.forEach(result=> {
          //do some work
       })
       return someDocRef2.update(....);
    });

    const p3 = db.collection("someOtherCollection3").get()
    .then(results => {
       results.forEach(result=> {
          //do some work
       })
       return someDocRef3.update(....);
    });

    Promise.all([p1, p2, p3])
    .then(() => {
        res.status(200).send("I waited for all the Queries AND the update operations inside the then blocks of queries to finish!")
    });

答案 1 :(得分:0)

如果您不想使函数成为异步函数,则可以执行以下操作:

const someCollectionRef
const someCollectionRef2
const someCollectionRef3

const promise1 = db.collection("someOtherCollection").get().then(results=> {
   results.forEach(result=> {
      //do some work
   })
   someCollectionRef.update(....);
})

const promise2 = db.collection("someOtherCollection2").get().then(results=> {
   results.forEach(result=> {
      //do some work
   })
   someCollectionRef2.update(....);
})

const promise3 = db.collection("someOtherCollection3").get().then(results=> {
   results.forEach(result=> {
      //do some work
   })
   someCollectionRef3.update(....);
})
Promise.all([promise1, promise2, promise3])
  .then(_ => res.status(200).send("I waited for all the Queries AND the update operations inside the then blocks of queries to finish!"));

答案 2 :(得分:-1)

也许您可以使用Promise.all来链接承诺。 Promise.all MDN

MDN的Promise演示:

var promise1 = Promise.resolve(3);
var promise2 = 42;
var promise3 = new Promise(function(resolve, reject) {
  setTimeout(resolve, 100, 'foo');
});

Promise.all([promise1, promise2, promise3]).then(function(values) {
  console.log(values);
});
// expected output: Array [3, 42, "foo"]