我已经为Firebase创建了一个计时器,但是当用户断开连接时,它无法正常工作。
问题:
计时器用于排队,因此所有用户都需要能够看到直到下一个人的当前时间。目前,我拥有这样的功能,即当用户单击队列按钮时,他们的客户端会减少剩余时间,使用Firebase方法.set()设置Firebase中的剩余时间,然后将Firebase值显示给所有用户。
此功能有效, 除外,当单击按钮的用户在计时器完成之前退出时,因为这将导致计时器停止递减。从功能上讲,我的目标是允许用户离开页面并返回,因此我想我可以在断开连接时重置计时器,但理想情况下,我希望计时器继续运行。
方法/想法:
我不确定该如何处理。我在考虑让客户端处理自己的计时器,有点像this answer,部分原因是有人提到使用interval()并不是计时器的最准确方法,但是我必须找到一种方法来允许之后输入的用户接收更新的时间。我可以通过让所有用户.set()设置Firebase时间来描述这一点,以便该页面的新用户可以看到剩余的更新时间,但是要让所有用户同时更新相同的数据似乎非常糟糕。我只是最近才开始研究交易,但是它们似乎很有希望,因为它们似乎能够处理许多用户试图更新相同值的情况,但是即使那样,我仍不确定这是最好的方法。我还考虑过拥有一种永远不会注销并管理所有用户时间的“主”客户端。
无论如何,下面是我的代码。我尝试仅包含相关代码,所以如果有任何不清楚的地方,请告诉我:
var database = firebase.database();
//firebase queue
var queueDB = firebase.database().ref().child("queue");
//get first person
varquery = firebase.database().ref("queue").orderByKey().limitToFirst(1);
let peopleInQueue;
//timer
var timerDB = firebase.database().ref().child("seconds");
let seconds_left = 100;
var timerState = firebase.database().ref("timerState");
let timer;
timerState.on("value", function(snapshot) {
timer= snapshot.val();
});
document.getElementById("queue").onclick = function() {
if (timer == "on") {
//prevent timer from decrementing more if already on
return;
}
timerState.set('on');
function setTimer() {
let interval = setInterval(function() {
if (timer == "on") {
//clident side
--seconds_left;
//sets Firebase time left value based on client time left value
timerDB.set(seconds_left);
}
if (seconds_left <= 0) {
//query to find first person in queue and remove them
query.once("value")
.then(function(snapshot) {
snapshot.forEach(function(childSnapshot) {
//key returns all the children nodes
let key = childSnapshot.key;
//reomve first person from queue
childSnapshot.ref.remove();
});
});
document.getElementById("timer_div").innerHTML = "You are Ready!";
clearInterval(interval);
seconds_left = 100;
timerDB.set(seconds_left);
//check to see if queue is done, if not repeat timer
if (peopleInQueue >= 2) {
setTimer();
}
else {
timerState.set('off');
}
}
}, 1000);
}
};