firebase云功能不能执行全部功能吗?

时间:2019-08-17 12:46:07

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

我有一个firebase云功能,该功能运行并检查firestore数据库中的对象并执行一些操作。但是它不会运行整个函数,而是会在函数中间随机停止。我首先认为它超时,但是超时值为60秒,我的函数在2-3秒内运行。但是大多数操作都需要承诺,因为它们正在执行异步操作,例如数据库操作。因此,为了确保函数在执行所有函数之前不会停止,我将它们推入promises数组并返回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函数中更好?需要帮助。预先感谢。

1 个答案:

答案 0 :(得分:2)

如果在代码中添加一些日志记录,则很容易看到正在发生的事情:

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来使承诺起泡,以便将其返回给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);
   })

})