【问题标题】:firebase cloud functions doesn't execute the whole function?firebase 云功能不执行整个功能?
【发布时间】:2019-12-23 11:20:12
【问题描述】:

我有一个 firebase 云函数,它运行并检查 firestore 数据库中的对象并执行一些操作。但它不会运行整个函数并随机停止在函数中间。我首先认为它超时但超时值为 60 秒,我的函数在 2-3 秒内运行。但是大多数操作都需要 Promise,因为它们正在执行异步操作,例如数据库操作。因此,为了确保函数在执行所有函数之前不会停止,我将它们推送到 Promise 数组中并返回 Promise.all(promises)。这是我的函数的样子

export const func = functions.pubsub.schedule('every 10 minutes').onRun(context => {
   const promises = any[] = [];
   //here I pass the array to some other function to gather the promises that are 
   //made there
   doSomeJob(promises)

   admin.firestore().collection('someCollection').get().then(res => {
        res.forEach(item => {
            let data = item.data();

            promises.push(somePromise);
            console.log('some Promise is pushed')
            promises.push(anotherPromise)
            .....
        })
   })

   return Promise.all(promises);
})

所以在上面的代码中,一些承诺被执行,一些则没有。不知道是什么原因。没有一个承诺会引发错误。但原因可能是它们甚至没有被推送到数组,因为我有时在日志部分看不到 console.log 运行。有时它运行有时它不运行。无法弄清楚为什么它会停在中间的某个地方。

我开始质疑我的设计了。也许我应该为我应该执行的每个承诺设置另一个功能。或者,例如,我有一个在更新对象时运行的函数。它应该做很多事情。我的意思是一堆读写。一堆承诺。那么,每个操作都使用另一个 onUpdate 函数,还是将它们全部放在一个 onUpdate 函数中更好呢?在这方面需要帮助。提前致谢。

【问题讨论】:

  • promises 数组被异步添加到 .then(res => { 内,当你 return Promise.all(promises); 时,这些 promise 不会在数组中
  • @JaromandaX 谢谢你是对的。这是整个问题。我实际上是在返回空的承诺列表,而 firebase 会在任何随机时间切断该函数的 cpu 访问。有时你看不到那么简单的东西:D

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


【解决方案1】:

如果您在代码中添加一些日志记录,就很容易看到发生了什么:

export const func = functions.pubsub.schedule('every 10 minutes').onRun(context => {
   const promises = any[] = [];
   //here I pass the array to some other function to gather the promises that are 
   //made there
   doSomeJob(promises)

   console.log('Before starting to read data...');
   admin.firestore().collection('someCollection').get().then(res => {
       console.log('Got data...');
   })
   console.log('After starting to read data...');

   return Promise.all(promises);
})

当你像这样运行代码时,它会记录:

开始读取数据之前...

开始读取数据后...

得到数据...

所以当您return Promise.all(...) 时,您还没有从 Firestore 获得数据,并且没有等待的承诺。因此 Cloud Functions 可能会随时终止运行您的代码的容器。

因此,解决方案是确保在您返回它们之前收集所有承诺。为此,您可以将 Promise.all(...) 放入回调中,然后使用另一个 return 将 Promise 冒泡,以便将其返回给 Cloud Functions。

export const func = functions.pubsub.schedule('every 10 minutes').onRun(context => {
   const promises = any[] = [];
   //here I pass the array to some other function to gather the promises that are 
   //made there
   doSomeJob(promises)

   return admin.firestore().collection('someCollection').get().then(res => {
        res.forEach(item => {
            let data = item.data();

            promises.push(somePromise);
            console.log('some Promise is pushed')
            promises.push(anotherPromise)
            .....
        })
        return Promise.all(promises);
   })

})

【讨论】:

  • 是的,你是对的。在函数实际结束后,我试图收集所有的承诺。
  • 很高兴一切顺利。如果这个或任何答案已经解决了您的问题,请考虑通过单击复选标记接受它。这向更广泛的社区表明您已经找到了解决方案,并为回答者和您自己提供了一些声誉。没有义务这样做。
猜你喜欢
  • 2018-11-07
  • 2019-07-14
  • 1970-01-01
  • 1970-01-01
  • 2018-06-15
  • 2021-10-26
  • 1970-01-01
  • 2020-06-09
  • 2019-10-15
相关资源
最近更新 更多