javascript - 等待函数firebase函数
问题描述
我正在尝试在 firebase 函数中为 Google Cloud 任务创建函数。我得到日志:
1:01:36.743 AM
start
1:01:38.644 AM
Start google timer
1:01:38.653 AM
Final
1:01:38.767 AM
Function execution took 4341 ms, finished with status: 'ok'
1:02:04.541 AM
Error: 4 DEADLINE_EXCEEDED: Deadline exceeded at Object.callErrorFromStatus
我一直在寻找信息并猜测这是由于执行不正确的异步/等待请求造成的。我没有足够的知识来理解这一点。我需要如何正确执行异步请求?我的代码示例:
exports.newTimer = functions.database
.instance("plan-b-b98f3-default-rtdb")
.ref("{userUID}/timers/{keyID}")
.onCreate(async (snapshot, context) => {
const value = snapshot.val();
await admin.database().ref(context.params.userUID + '/push').once('value', (snapshotPush) => {
functions.logger.info("start");
return ScheduleRequest(value, snapshot.key).then(() => {
functions.logger.info("success create cloud task", {structuredData: true});
}).catch((e) => {
functions.logger.error(e, {structuredData: true})
});
}, (errorObject) => {
functions.logger.error('The read push tokens failed: ' + errorObject.name, {structuredData: true})
});
functions.logger.info("Final");
});
const ScheduleRequest = async (timerKey, timer) => {
const project = 'plan-b-b98f3';
const location = 'us-central1';
const queue = 'plnbtimers';
const tasksClient = new CloudTasksClient();
const queuePath = tasksClient.queuePath(project, location, queue);
const url = `https://${location}-${project}.cloudfunctions.net/endTimerPush`;
const json = {id: timerKey};
functions.logger.info("Start google timer", {
id: timerKey,
total: timer.created + timer.duration
});
const task = {
httpRequest: {
httpMethod: 'POST',
url,
body: Buffer.from(JSON.stringify(json)).toString('base64'),
headers: {
'Content-Type': 'application/json',
},
},
scheduleTime: {
seconds: timer.created + timer.duration
}
}
return await tasksClient.createTask({parent: queuePath, task});
};
解决方案
该Schedule Request
函数对我来说看起来不错,但尝试newTimer
像这样重构函数:
exports.newTimer = functions.database
.instance("plan-b-b98f3-default-rtdb")
.ref("{userUID}/timers/{keyID}")
.onCreate(async (snapshot, context) => {
try {
const value = snapshot.val();
const snapshotPush = await admin.database().ref(context.params.userUID + '/push').once('value')
// if (!snapshot.val()) return false
functions.logger.info("start");
await ScheduleRequest(value, snapshot.key)
functions.logger.info("success create cloud task", { structuredData: true });
return null
} catch (errorObject) {
functions.logger.error('The read push tokens failed: ' + errorObject.name, { structuredData: true })
functions.logger.info("Final");
return null
}
});
你拿来snapshotPush
干嘛?您是否只是检查该值是否存在?如果是,请取消注释返回 false 的行。
另一个重要的事情是您必须终止后台功能。注意return null
语句。或者,您也可以像这样返回该承诺:
return ScheduleRequest(value, snapshot.key)
推荐阅读
- mysql - 大于和小于日期在 sequelize 中没有记录,但可以与 heidisql 一起使用
- reactjs - React / Redux - 异步操作在不使用 thunk 的情况下工作
- css - 如何使用 scrapy(网页抓取)导航到下一页
- visual-studio-code - VS Code:寻找通过编程语言对其他扩展进行分组的扩展
- java - GenerationTarget 遇到异常接受命令:通过 JDBC 语句执行 DDL 引擎 = MyISAM 时出错
- azure - 在公共容器上获取“AuthorizationPermissionMismatch”
- javascript - PhpStorm 发出奇怪的信息
- javascript - 如何正确地将 graphql 突变推送到组件的道具中?
- r - 如何使用 paste() 在 Rmarkdown Word 标题中添加换行符?
- mysql - 如何不为 MySQL 表选择列,它是否使查询更快