我有一个Firebase Cloud功能,该功能每天在股市开盘时触发一次。似乎在运行20%的时间时会产生错误。
错误说:“错误:函数崩溃超出了请求范围。函数调用被中断。”
export async function cleanIntraweek() {
console.log(`cleanIntraweek() started`)
const min_date_key = moment().tz("America/New_York").subtract(7, 'day').format()
console.log(`min_date_key: ${min_date_key}`)
//helper async function to grab some data
const enabled_stock_keys = await FirebaseObjectFetchService.getStockKeys(true)
const fetch_intraweek_dataset_promises: Promise<any>[] = []
const clear_data_promises: Promise<any>[] = []
for (const stock_key of enabled_stock_keys) {
const fetch_intraweek_dataset_promise =
db
.ref(`charts/${stock_key}/intraweek_v3`)
.orderByKey()
.endAt(min_date_key)
.once("value")
.then((snapshot) => {
snapshot.forEach((child_snapshot) => {
const clear_data_promise = child_snapshot.ref.remove()
clear_data_promises.push(clear_data_promise)
return false
});
})
fetch_intraweek_dataset_promises.push(fetch_intraweek_dataset_promise)
}
console.log("waiting on fetch_intraweek_dataset_promises")
await Promise.all(fetch_intraweek_dataset_promises)
console.log("waiting on clear_data_promises")
await Promise.all(clear_data_promises).then(() => {console.log("cleanIntraweek() finished")})
return null
}
我不记得在Node 6引擎上运行云功能时遇到此错误。从Node 8引擎(当前)恢复为Node 6引擎不是解决方案,因为Firebase Cloud Functions会在一年内取消对Node 6引擎的支持。
我见过this post,但是据我所知,我没有在函数返回之前没有等待的任何诺言。
答案 0 :(得分:0)
此错误通常意味着您应该运行一些异步代码,并在该功能应该完全完成之后引发了执行。这意味着您实际上没有正确处理函数中的所有promise。问题似乎在这里发生:
.then((snapshot) => {
snapshot.forEach((child_snapshot) => {
const clear_data_promise = child_snapshot.ref.remove()
clear_data_promises.push(clear_data_promise)
return false
});
})
您有一个Promise回调,它异步创建更多的Promise以删除子节点。但是,这里没有任何东西可以保证clear_data_promises
会在之前完全填充,之后再等待承诺列表。换句话说,await Promise.all(clear_data_promises)
可以在保证clear_data_promises
完全填充之前执行,因为forEach lambda本身不会阻塞每个操作的结果。
您要做的是确保上面的then
回调函数返回一个promise,该promise跟踪forEach Labmda内部的所有内部promise。仅在所有下级工作完成后,fetch_intraweek_dataset_promise
承诺才能得到解决。与此类似:
.then((snapshot) => {
const clear_data_promises = []
snapshot.forEach((child_snapshot) => {
const clear_data_promise = child_snapshot.ref.remove()
clear_data_promises.push(clear_data_promise)
return false
});
return Promise.all(clear_data_promises)
})
然后,您不必稍后再等待该阵列。一切都将通过fetch_intraweek_dataset_promises
解决。