我正在尝试创建一个云功能,但是在firebase的日志中,它在完成所有任务之前显示为“完成”。
这是我的代码。
export const count = functions.pubsub
.schedule('0 8 * * *')
.timeZone('Europe/Brussels')
.onRun(async context => {
const snapshot = await admin.database().ref('/counter').once('value');
snapshot.forEach( (child) =>
{
var info = child.val();
var dayViews = info['count'];
var ID = child.key;
var ref1 = admin.database().ref('/counter/'+ID);
ref1
.update({
"count": 0,
"totalViews": dayViews,
})
.then(function() {
console.log("Write completed")
}).catch(function(error) {
console.error("Write failed: "+error)
});
});
return 0;
});
我认为问题在于函数在完成每个循环的操作之前返回0。
对此有解决方案吗?
谢谢!
答案 0 :(得分:1)
解决方案是在调用return之前等待所有异步update()
操作完成:由于您使用forEach()
循环,因此需要使用Promise.all()
来等待在循环中调用的所有异步操作都必须在返回它返回的Promise之前完成。
如文档(上面的链接)所述,Promise.all()
“通常在启动多个异步任务并发运行并为其结果创建承诺后使用,等待所有任务完成。”
以下应该可以解决问题:
export const count = functions.pubsub
.schedule('0 8 * * *')
.timeZone('Europe/Brussels')
.onRun(async context => {
const snapshot = await admin.database().ref('/counter').once('value');
const promises = [];
snapshot.forEach((child) => {
var info = child.val();
var dayViews = info['count'];
var ID = child.key;
var ref1 = admin.database().ref('/counter/' + ID);
promises.push(ref1
.update({
"count": 0,
"totalViews": dayViews,
}));
});
return Promise.all(promises)
});
关于正确处理Cloud Function中的异步操作的关键所在,我建议您观看Firebase视频系列中有关“ JavaScript Promises”的3个视频:https://firebase.google.com/docs/functions/video-series/