我有一个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函数中更好?需要帮助。预先感谢。
答案 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);
})
})