javascript - 我在云功能中的计时器在第二次通话后停止
问题描述
我的应用程序是一个多人游戏,玩家可以在其中创建一个会话,每个会话都有一个独特的sessionID
并且包含许多回合,并且每个回合都有自己的计时器。
我做了一个用于实现计时器的云功能。它工作得很好,但是如果session1
启动它的计时器然后session2
启动它自己的计时器。发生的事情是计时器session1
停止了!
我用javascript编写的函数,它每秒更新firebase中实时数据库中的计时器。
云功能代码
exports.RoundTimerS = functions.database.ref('/Sessions/{sessionid}/onCamera')
.onCreate((snap, context) => {
var SessionID = context.params.sessionid
sessionref4 = "/Sessions/".concat(SessionID);
sessionref4 = sessionref4.concat("/Timer");
sessionref5 = "/Sessions/".concat(SessionID);
sessionref5 = sessionref5.concat("/numOfPlayers");
sessionref6 = "/Sessions/".concat(SessionID);
sessionref6 = sessionref6.concat("/NumberOfFinish");
Roundtimer = 60 //60s
var player = 0
var db = admin.database();
var ref = db.ref(sessionref5);
var ref2 = db.ref(sessionref6);
ref.once("value", function (snapshot2) {
player = snapshot2.val()
}, function (errorObject) {
console.log("The read failed: " + errorObject.code);
});
var Timer = setInterval(function () {
admin.database()
.ref(sessionref4 + "/Roundtimer1").set(Roundtimer)
ref2.once("value", function (snapshot) {
if (snapshot.numChildren() == player) {
clearInterval(Timer)//Stop timer
}
}, function (errorObject) {
console.log("The read failed: " + errorObject.code);
});
if (Roundtimer <= 0) { //Round Timer finish
admin.database()
.ref(sessionref4 + "/Roundtimer1").set(Roundtimer)
clearInterval(Timer)//Stop timer
}
Roundtimer -= 1
解决方案
Cloud Functions 会一直运行到}
它们的代码结束,也就是你的计时器结束之前。因此,您的容器在计时器完成之前被回收。
如果您希望容器为任何异步操作保持活动状态,则需要返回一个承诺,该承诺在所有工作完成后解决。
exports.RoundTimerS = functions.database.ref('/Sessions/{sessionid}/onCamera')
.onCreate((snap, context) => {
return new Promise((resolve, reject) => {
var SessionID = context.params.sessionid
sessionref4 = "/Sessions/".concat(SessionID);
sessionref4 = sessionref4.concat("/Timer");
sessionref5 = "/Sessions/".concat(SessionID);
sessionref5 = sessionref5.concat("/numOfPlayers");
sessionref6 = "/Sessions/".concat(SessionID);
sessionref6 = sessionref6.concat("/NumberOfFinish");
Roundtimer = 60 //60s
var player = 0
var db = admin.database();
var ref = db.ref(sessionref5);
var ref2 = db.ref(sessionref6);
ref.once("value", function (snapshot2) {
player = snapshot2.val()
}, function (errorObject) {
console.log("The read failed: " + errorObject.code);
});
var Timer = setInterval(function () {
db.ref(sessionref4 + "/Roundtimer1").set(Roundtimer)
ref2.once("value", function (snapshot) {
if (snapshot.numChildren() == player) {
clearInterval(Timer)//Stop timer
}
}, function (errorObject) {
console.log("The read failed: " + errorObject.code);
});
if (Roundtimer <= 0) { //Round Timer finish
db.ref(sessionref4 + "/Roundtimer1").set(Roundtimer).then(() =
> {
resolve(); // this seems to be where your timer is done
})
clearInterval(Timer)//Stop timer
}
Roundtimer -= 1
...
});
请注意,这并不意味着是复制/粘贴解决方案,而是您应该采取的方法的概述。这是:
- 返回一个承诺。
- 确定工作已完成。
我强烈建议您阅读 Cloud Functions 中的异步工作,因为在您控制住它之前,您会一直遇到问题。一些不错的资源:
推荐阅读
- javascript - js中的倒数计时器与服务器同步
- python - 遍历树时递归不起作用
- typescript - Firebase 错误通过函数写入 Firestore:“7 PERMISSION_DENIED:缺少或不足的权限”
- javascript - 动态更改顶点位置后网格位置无效
- css - 根据包装器而不是屏幕尺寸设置断点
- r - 基于两列在R中成对排列行
- python - 如何从 3D numpy meshgrid 中提取 2D 平面
- c# - 不要在外部条件下序列化字段C#
- r - R:使用方法中的错误(“tbl_vars”)
- python - 与 Exasol 的 Python 连接 - 导出到 pandas