Дождитесь завершения запросов в хранилище, прежде чем возвращать ответ облачной функции. - PullRequest
1 голос
/ 25 июня 2019

У меня есть облачная функция, которая запускает 3 запроса в хранилище в 3 разных коллекциях.Каждый запрос имеет цикл foreach внутри блока then, и после цикла 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 ]

1 голос
/ 25 июня 2019

Если вы вызываете некоторые асинхронные методы Firestore в своей облачной функции (например, get() для CollectionReference или update() для DocumentReference), вам просто нужноцепочка различных обещаний, возвращаемых этими методами.

Итак, основываясь на коде вашего вопроса, вы можете изменить его следующим образом:

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

Обратите внимание, что это будет работать, поскольку число someCollectionRefs и someDocRefs известно заранее.,Если у вас есть переменное число асинхронных операций для выполнения, вам нужно будет использовать метод 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!")
    });
0 голосов
/ 25 июня 2019

Если вы не хотите делать свою функцию асинхронной, вы можете сделать что-то вроде этого:

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!"));
0 голосов
/ 25 июня 2019

Возможно, вы могли бы использовать Promise.all, чтобы связать обещания. Promise.all MDN

Демо Promise от MDN:

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"]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...