所以我有这个处理投票和计时器的模块。当投票进入并且满足其有效的 AND 投票阈值时。它启动计时器。现在,这导致了一个无限循环,当计时器完成时,它会创建一个新计时器并运行它。如果发生这种情况,我会假设我会看到多个计时器并排运行,但我假设它们是堆叠在一起的。
const { r } = require('./redisClient');
const axios = require('axios');
let userVotes = {};
let viewerCount = 0;
let votingThreshold = viewerCount/2;
const handleMessage = async (channel, tags, message, self) => {
//if msg is greater than 1 character, ignore.
const vote = parseInt(message, 10);
if (vote >= 1 && vote <= 32) {
console.log(`${tags.username} voted for ${vote}`);
// Calculate grid position based on the vote.
const rowIndex = Math.floor((vote - 1) / 8);
const colIndex = (vote - 1) % 8;
// Check if the vote is valid by checking its Redis value.
let grid = await r.get('Grid'+(rowIndex)); // Assuming you're storing data in Redis in this string format.
grid = JSON.parse(grid);
const gridValue = grid[colIndex][2];
console.log(gridValue);
if (gridValue === 2|| gridValue === 3 && grid[colIndex][3] !== 'True') {
//if the user has already voted, remove their previous vote from the grid
if (tags.username in userVotes) {
const previousVote = userVotes[tags.username];
const previousRowIndex = Math.floor((previousVote - 1) / 8);
const previousColIndex = (previousVote - 1) % 8;
grid[previousColIndex][0] -= 1;
}
//add user's vote to userVotes
userVotes[tags.username] = vote;
console.log('vote valid');
//increase grid vote by 1
grid[colIndex][0] += 1;
r.set(`Grid`+(rowIndex), JSON.stringify(grid));
//if user has already voted, remove their previous vote
if (Object.keys(userVotes).length >=votingThreshold) {
startTimer();
}
console.log(Object.keys(userVotes).length)
r.set(`VoteCount`, JSON.stringify(Object.keys(userVotes).length));
}
else {
console.log('not a valid vote.');
}
}
};
resetUserVotes = () =>
userVotes = {}
resetGridVotes = async () => {
//if a grid item is 2 or 3, set its [0] to 0
for (let i = 0; i < 4; i++){
console.log('Grid'+i);
let grid = await r.get('Grid'+i); // Assuming you're storing data in Redis in this string format.
grid = JSON.parse(grid);
for (let j = 0; j < grid.length; j++){
if (grid[j][2] === 2 || grid[j][2] === 3){
grid[j][0] = 0;
grid[j][2] = 2;
}
}
r.set('Grid'+i, JSON.stringify(grid));
}
console.log('Grid votes have been reset.');
};
getTopVoted = () => {
if (Object.keys(userVotes).length === 0) {
return null;
}
const votes = Object.values(userVotes);
const topVote = votes.reduce((a, b) => {
return votes.filter(vote => vote === a).length >= votes.filter(vote => vote === b).length ? a : b;
}, null);
return topVote;
};
let topVoted = null;
updateTopVoted = async () => {
console.log(isVotingActive);
currentVote = getTopVoted();
if (isVotingActive === false){
return
}
if (currentVote === null) {
console.log('No votes yet.');
setTimeout(updateTopVoted, 1000);
return;
}
if (topVoted !== currentVote) {
//set grid top voted to 2 and grid current vote to 3
const rowIndex = Math.floor((currentVote - 1) / 8);
const colIndex = (currentVote - 1) % 8;
let grid = await r.get(`Grid`+rowIndex); // Assuming you're storing data in Redis in this string format.
grid = JSON.parse(grid);
grid[colIndex][2] = 3;
if (topVoted !== null) {
const rowIndex = Math.floor((topVoted - 1) / 8);
const colIndex = (topVoted - 1) % 8;
grid[colIndex][2] = 2;
}
topVoted = currentVote;
r.set(`Grid`+rowIndex, JSON.stringify(grid));
console.log(`Top voted is now ${topVoted}`);
setTimeout(updateTopVoted, 1000);
}
else {
setTimeout(updateTopVoted, 1000);
console.log(`Top voted is still ${topVoted}`);
}
};
let timer = 20;
const timerDefault = 20;
const startTimer = () => {
if (timer > 0) {
console.log(timer);
timer--;
r.set(`Timer`, JSON.stringify(timer));
console.log('Timer running...' + timer);
setTimeout(startTimer, 1000);
} else {
console.log('Timer finished!');
stopVoting();
pauseEvents();
openCase();
timer = timerDefault;
}
};
const openCase = () => {
//16 will be col 8 row 1
//17 will be col 0 row 2
//18 will be col 1 row 2
//19 will be col 2 row 2
//24 will be col 0 row 3
colIndex = (topVoted - 1) % 8;
rowIndex = Math.floor((topVoted - 1) / 8);
const c = colIndex;
const r = rowIndex;
axios.post(`http://localhost:5000/openCase?topVoted=${topVoted}&c=${c}&r=${r}`)
.then(res => {
console.log(res.data);
startVoting();
}
);
};
const startVoting = () => {
isVotingActive = true;
client.on('message', handleMessage); // Attach the event listener
console.log('Voting has started!');
resetGridVotes();
updateTopVoted();
resetUserVotes();
resumeEvents();
};
const stopVoting = () => {
isVotingActive = false;
client.removeListener('message', handleMessage); // Remove the event listener
console.log('Voting has stopped!');
};
const updateViewers = async (newViewers) => {
viewerCount = parseInt(newViewers);
votingThreshold = Math.floor(viewerCount / 2);
console.log(viewerCount)
console.log(`Viewers has been set to ${newViewers}`);
r.set(`LiveViewerCount`, JSON.stringify(viewerCount));
};
const pauseEvents= (req,res) => {
axios({
method: 'post',
url: 'http://127.0.0.1:1234/DoAction',
data: {
"action": {
"id": "2a094d23-55aa-46cc-ad98-01bf5224f9ad",
"name": "pause"
},
}
})
};
const resumeEvents = (req,res) => {
axios({
method: 'post',
url: 'http://127.0.0.1:1234/DoAction',
data: {
"action": {
"id": "56935fa0-3325-4f3a-8c02-e9005f246a96",
"name": "resume"
},
}
})
}
// more voting-related functions
module.exports = {
handleMessage,
resetUserVotes,
resetGridVotes,
startTimer,
startVoting,
stopVoting,
updateTopVoted,
openCase,
timer,
updateViewers
};
日志复制
No votes yet.
true
No votes yet.
true
No votes yet.
zekimar voted for 1
2
vote valid
20
Timer running...19
1
true
Top voted is now 1
19
Timer running...18
true
Top voted is still 1
18
Timer running...17
true
Top voted is still 1
17
Timer running...16
true
Top voted is still 1
5
5
Viewers has been set to 5
Viewers has been set to 5
16
Timer running...15
true
Top voted is still 1
15
Timer running...14
true
Top voted is still 1
14
Timer running...13
true
Top voted is still 1
mapefy voted for 2
2
vote valid
13
Timer running...12
2
12
Timer running...11
true
Top voted is still 1
zachtie voted for 1
3
vote valid
11
Timer running...10
3
10
Timer running...9
9
Timer running...8
smoooore voted for 8
2
vote valid
8
Timer running...7
4
true
Top voted is still 1
7
Timer running...6
6
Timer running...5
5
Timer running...4
4
Timer running...3
true
Top voted is still 1
3
Timer running...2
2
Timer running...1
1
Timer running...0
Timer finished!
Voting has stopped!
false
20
Timer running...19
19
Timer running...18
18
Timer running...17
17
Timer running...16
16
Timer running...15
15
Timer running...14
14
Timer running...13
13
Timer running...12
12
Timer running...11
11
Timer running...10
10
Timer running...9
9
Timer running...8
8
Timer running...7
7
Timer running...6
6
Timer running...5
5
Timer running...4
4
Timer running...3
3
Timer running...2
2
Timer running...1
1
Timer running...0
Timer finished!
Voting has stopped!
20
Timer running...19
19
Timer running...18
18
Timer running...17
17
Timer running...16
16
Timer running...15
15
Timer running...14
14
Timer running...13
13
Timer running...12
12
Timer running...11
11
Timer running...10
10
Timer running...9
9
Timer running...8
8
Timer running...7
7
Timer running...6
6
Timer running...5
5
Timer running...4
4
Timer running...3
3
Timer running...2
2
Timer running...1
1
Timer running...0
Timer finished!
Voting has stopped!
20
Timer running...19
19
Timer running...18
18
Timer running...17
17
Timer running...16
16
Timer running...15
15
Timer running...14
14
Timer running...13
13
Timer running...12
12
Timer running...11
11
Timer running...10
10
Timer running...9
========PROGRAM WAS TERMINATED HERE BY AN EXCEPTION IN ANOTHER PART OF THE CODE===========
I have tried to make a isTimerActive Boolean. I wansnt able to replicate the conditions as this code can only run in the feild and I have limited helpers. This error has not happened on other similar cases despite me thinking it should break more often.
问题似乎出在你的时间函数上,只有当你知道如何摆脱它时,递归才有用,它会给你的代码造成很多破坏。
let timer = 20;
const timerDefault = 20;
const startTimer = () => {
if (timer > 0) { //2
console.log(timer);
timer--;
r.set(`Timer`, JSON.stringify(timer));
console.log('Timer running...' + timer);
setTimeout(startTimer, 1000); // 1
} else {
console.log('Timer finished!');
stopVoting();
pauseEvents();
openCase();
timer = timerDefault; //3
}
};
您不断在 setTimeout 中传递函数本身,并且计时器> 0,您不断传递它 - 在这种情况下,它将被调用 19 次。
在第 19 次尝试时,当计时器为 0 时,它将转到您将计时器再次设置为 20 的其他地方。当您通过
startTimer
时,它会创建一个指向计时器的闭包,并且所有其他调用都指向指向到同一个变量 - 计时器。
我不知道为什么你希望它设置为这样的默认值。
到底为什么定时器在完成后又再次运行。看日志 文件以查看投票后未再次调用句柄消息。
这是因为您正在将计时器值更新为默认值,并且它位于闭包范围内,并且会将所有现有计时器函数的计时器重置为默认值。
运行以下代码并检查浏览器中的控制台。
let timer = 20;
const timerDefault = 20;
const startTimer = () => {
if (timer > 0) { //2
console.log(timer);
timer--;
//r.set(`Timer`, JSON.stringify(timer));
console.log('Timer running...' + timer);
console.dir(startTimer) // here you can check the scopes array - check the script one that points to closure
setTimeout(startTimer, 1000); // 1
} else {
console.log('Timer finished!')
timer = timerDefault; //3
}
};
startTimer();
我应该怎么做才能做到这一点。我是编码新手,这是我的 最大的项目。请随时让我知道我犯了错误:D
从提示来看,我还是不确定你想要达到什么目的。如果你可以更新提示。我可以尝试为您指出正确的方向。
注意:请检查此链接以了解关闭