clearTimeout 函数不 运行
clearTimeout function does not run
我使用 socket.io 制作了一个问答游戏。当一个新套接字连接时,运行:
io.on('connection', function (socket) {
let gameTimer = null;
从客户端接收到某个套接字后,该函数启动:
gameTimer = setTimeout(function () {
//Reveal if the players' answers are right or wrong
revealAnswer(answeredPlayers, playerData[socket.id].room);
//Start the countdown for the next question
countToNextQuestion(playerData[socket.id].room);
}, 21000)
当玩家应答时,此套接字函数在服务器中运行:
socket.on('Answered Question', function (userAnswer, answeredPlayerUsername, timeAnswered) {
//Stop the count
clearTimeout(gameTimer);
/*
*Extra code below that works...
*/
但这并不能阻止超时。发生这种情况的任何原因,以及如何解决它?
编辑:这是完整的套接字代码。有点长,抱歉:
io.on('connection', function (socket) {
console.log('Someone connected');
//Will hold the questions used for the session
let gameSessionQuestions = null;
//Holds the current question
let currentQuestion = null;
//Holds the correct answer to the current question
let currentQuestionAnswer = null;
//Give the socket player details
//and add this player to the dictionary
playerData[socket.id] = {
name: null,
room: null,
host: false,
score: 0
};
//Timer for questions
let gameTimer = null;
/*
SOCKET OPERATIONS
*/
socket.on('Get Total Score', async function(playerUsername){
let playerTotalScore = await gameController.getTotalScore(playerUsername);
socket.emit('Receive Total Score', playerTotalScore);
})
//Adds a room to the list of rooms
socket.on('Add Room', function (questionType) {
let newRoom = newRoomCreation(questionType);
//Since this player created the room, assign them the host value
playerData[socket.id].host = true;
playerData[socket.id].room = newRoom;
socket.join(newRoom);
io.sockets.to(newRoom).emit('Room Added', newRoom);
})
//Make the specified room a closed room
socket.on('Close the room', function (room) {
closeRoom(room);
})
socket.on('Room Availability', function (roomCode, questionType) {
if (!roomMap.get(roomCode)) {
socket.emit('Unavailable Room');
}
else {
//Check if the room has the question type the user chose
if (roomQuestionType.get(roomCode) == questionType) {
socket.emit('Available Room');
} else {
socket.emit('Unavailable Room');
}
}
})
socket.on('Open Room Availability', function (questionType) {
let roomFound = false;
for (let room of roomMap.keys()) {
if (!closedRoomsList.includes(room)) {
if (roomQuestionType.get(room) == questionType) {
roomFound = true;
socket.emit('Available Open Room', room);
}
}
}
if (roomFound == false) {
socket.emit('Unavailable Open Room');
}
})
socket.on('Join Room', function (values) {
//Give this player's 'name' variable a value
playerData[socket.id].name = values.p1;
//Give this player's 'room' variable a value
playerData[socket.id].room = values.p2;
//DELETE SOON: Checking the data before addition
console.log("Data in the room '" + values.p2 + "' before addition: ");
console.log(roomMap.get(values.p2));
//Put this player in the new room
socket.join(values.p2);
//Add the player's socketID and Name to the Room Map
let playersList = roomMap.get(values.p2);
playersList.push(values.p1);
//DELETE SOON: Checking the data after addition
console.log("Data in the room '" + values.p2 + "' after addition: ");
console.log(roomMap.get(values.p2));
io.sockets.to(values.p2).emit('Output Players', playersList);
if (playerData[socket.id].host == true) {
io.sockets.to(playerData[socket.id].room).emit('Current Host');
}
})
socket.on('Request Game Start', async function (room) {
//Checks if the user who started the game truly is the host
if (playerData[socket.id].host == false) {
return;
}
//Holds all the questions to be asked and their answers
gameSessionQuestions = await selectedQuestions(2, roomQuestionType.get(room));
//Reset the 'answered player' count
answeredPlayers.set(playerData[socket.id].room, 0);
io.sockets.to(room).emit('Game Start');
})
socket.on('Start Game Countdown', function () {
let pos = 0;
let countArr = ["2", "1", "Go"];
let counter = setInterval(function () {
//Update the count for all those in the room
io.sockets.to(playerData[socket.id].room).emit('Update Countdown', countArr[pos]);
if (pos == countArr.length) {
clearInterval(counter);
io.sockets.to(playerData[socket.id].room).emit('End Countdown');
currentQuestion = getQuestion(gameSessionQuestions[0], playerData[socket.id].room);
io.sockets.to(playerData[socket.id].room).emit('Receive Questions', currentQuestion);
//Holds the answer for the current question
currentQuestionAnswer = currentQuestionCorrectAnswer(gameSessionQuestions[0], playerData[socket.id].room);
//The answer to the question presented in this room is stored here
questionAnswers.set(playerData[socket.id].room, currentQuestionAnswer);
gameTimer = setTimeout(function () {
//Reveal if the players' answers are right or wrong
revealAnswer(answeredPlayers, playerData[socket.id].room);
//Start the countdown for the next question
countToNextQuestion(playerData[socket.id].room);
}, 21000)
} else {
pos++;
}
}, 1000);
})
socket.on('Answered Question', function (userAnswer, answeredPlayerUsername, timeAnswered) {
socket.broadcast.to(playerData[socket.id].room).emit('Display Answered Player', answeredPlayerUsername);
//DELETE SOON: Check the current question
console.log("Current Question's Answer: " + questionAnswers.get(playerData[socket.id].room));
console.log("Your answer: " + userAnswer);
let answerResult;
if (questionAnswers.get(playerData[socket.id].room) === userAnswer) {
answerResult = "btn-success";
//Add to the person's overall score
playerData[socket.id].score = addToScore(playerData[socket.id].score, timeAnswered);
socket.emit('Answer Check', answerResult);
}
else {
answerResult = "btn-danger";
socket.emit('Answer Check', answerResult);
}
//DELETE SOON: Checks the scores for the user
console.log("The score for '" + playerData[socket.id].name + "' is '" + playerData[socket.id].score + "'")
//Add 1 to the number of people who have answered in this room
answeredPlayers.set(playerData[socket.id].room, (answeredPlayers.get(playerData[socket.id].room)) + 1)
//DELETE SOON: Checks if the value is updating
console.log("Number of people who have answered: " + answeredPlayers.get(playerData[socket.id].room))
//If all users in the room have answered...
if (answeredPlayers.get(playerData[socket.id].room) == (roomMap.get(playerData[socket.id].room)).length) {
//DELETE SOON: Outputs message confirming all users answering
console.log("Everyone has answered");
//Stop the count
clearTimeout(gameTimer);
//Reveal if the players' answers are right or wrong
revealAnswer(answeredPlayers, playerData[socket.id].room);
//Start the countdown for the next question
countToNextQuestion(playerData[socket.id].room);
}
})
//Get the next question from the host
socket.on('Find Host', async function () {
if (playerData[socket.id].host == true) {
//DELETE SOON: Check the number of questions before
console.log('Question count before: ' + gameSessionQuestions.length)
gameSessionQuestions.shift();
//DELETE SOON: Check the number of questions after removing the one just asked
console.log('Question count after: ' + gameSessionQuestions.length)
//If there are still questions to be asked, send the next question and set the new correct answer
if (gameSessionQuestions.length != 0) {
//Get the next question and send it
currentQuestion = getQuestion(gameSessionQuestions[0], playerData[socket.id].room);
io.sockets.to(playerData[socket.id].room).emit('Receive Questions', currentQuestion);
//Get this question's correct answer
currentQuestionAnswer = currentQuestionCorrectAnswer(gameSessionQuestions[0], playerData[socket.id].room);
questionAnswers.set(playerData[socket.id].room, currentQuestionAnswer);
gameTimer = setTimeout(function () {
//Reveal if the players' answers are right or wrong
revealAnswer(answeredPlayers, playerData[socket.id].room);
//Start the countdown for the next question
countToNextQuestion(playerData[socket.id].room);
}, 21000)
} else {
//Holds the username and scores for all users in this room
let players_Scores = [];
let roomCode = playerData[socket.id].room;
let playerKeys = Object.keys(playerData);
for (let i = 0; i < playerKeys.length; i++) {
if (playerData[playerKeys[i]].room == roomCode) {
let scoreDetails = {
username: playerData[playerKeys[i]].name,
score: playerData[playerKeys[i]].score
}
players_Scores.push(scoreDetails)
await gameController.uploadScore(playerData[playerKeys[i]].name, playerData[playerKeys[i]].score, roomQuestionType.get(roomCode));
}
}
io.sockets.to(roomCode).emit('Show Scores', players_Scores);
}
}
})
//Remove details while reloading the menu page
socket.on('Back to Start', function () {
//Remove the player from the room in socketio
socket.leave(playerData[socket.id].room);
//If this is the host, delete the room
if (playerData[socket.id].host == true) {
roomMap.delete(playerData[socket.id].room);
roomQuestionType.delete(playerData[socket.id].room);
questionAnswers.delete(playerData[socket.id].room);
answeredPlayers.delete(playerData[socket.id].room);
}
//Remove this player's details
delete playerData[socket.id];
})
socket.on('disconnect', function () {
if (playerData[socket.id] && roomMap.get(playerData[socket.id].room) != undefined) {
//DELETE SOON: Check who left and from which room
console.log(playerData[socket.id].name + " has left the room '" + playerData[socket.id].room + "'");
//If on the lobby page, remove that player and update everyone's lists
let playerList = roomMap.get(playerData[socket.id].room);
playerList.splice(playerList.indexOf(playerData[socket.id].name), 1);
io.sockets.to(playerData[socket.id].room).emit('Output Players', playerList);
/*If this is the host,
* stop game timer
* alert all the players in the room,
* delete the room they were in*/
if (playerData[socket.id].host == true) {
clearTimeout(gameTimer);
socket.broadcast.to(playerData[socket.id].room).emit('Host Left');
roomMap.delete(playerData[socket.id].room);
roomQuestionType.delete(playerData[socket.id].room);
questionAnswers.delete(playerData[socket.id].room);
answeredPlayers.delete(playerData[socket.id].room);
}
delete playerData[socket.id];
}
})
})
好像是访问变量的时候出错,但是没有完整的代码,是不行的
你的问题用最少的代码来表示
let gameTimer;
let pos = 0;
let countArr = ["2", "1", "Go"];
let counter = setInterval(function () {
if (pos == countArr.length) {
console.log("Creating a new gameTimer", Date.now());
gameTimer = setTimeout(function () {
console.log('gameTimer executed')
}, 2100);
} else {
pos++;
}
}, 1000);
因此您的代码不断创建新的超时。以前的超时存在,它们不会被删除。
因此您需要在创建新游戏计时器之前删除 gameTimer,或者如果它已经是 运行
,则不要创建 gameTimer
let gameTimer;
let pos = 0;
let countArr = ["2", "1", "Go"];
let counter = setInterval(function () {
if (pos == countArr.length) {
if (gameTimer) return; // if gameTimer is defined, exit
console.log("Creating a new gameTimer", Date.now());
gameTimer = setTimeout(function () {
console.log('gameTimer executed')
}, 2100);
} else {
pos++;
}
}, 1000);
我使用 socket.io 制作了一个问答游戏。当一个新套接字连接时,运行:
io.on('connection', function (socket) {
let gameTimer = null;
从客户端接收到某个套接字后,该函数启动:
gameTimer = setTimeout(function () {
//Reveal if the players' answers are right or wrong
revealAnswer(answeredPlayers, playerData[socket.id].room);
//Start the countdown for the next question
countToNextQuestion(playerData[socket.id].room);
}, 21000)
当玩家应答时,此套接字函数在服务器中运行:
socket.on('Answered Question', function (userAnswer, answeredPlayerUsername, timeAnswered) {
//Stop the count
clearTimeout(gameTimer);
/*
*Extra code below that works...
*/
但这并不能阻止超时。发生这种情况的任何原因,以及如何解决它?
编辑:这是完整的套接字代码。有点长,抱歉:
io.on('connection', function (socket) {
console.log('Someone connected');
//Will hold the questions used for the session
let gameSessionQuestions = null;
//Holds the current question
let currentQuestion = null;
//Holds the correct answer to the current question
let currentQuestionAnswer = null;
//Give the socket player details
//and add this player to the dictionary
playerData[socket.id] = {
name: null,
room: null,
host: false,
score: 0
};
//Timer for questions
let gameTimer = null;
/*
SOCKET OPERATIONS
*/
socket.on('Get Total Score', async function(playerUsername){
let playerTotalScore = await gameController.getTotalScore(playerUsername);
socket.emit('Receive Total Score', playerTotalScore);
})
//Adds a room to the list of rooms
socket.on('Add Room', function (questionType) {
let newRoom = newRoomCreation(questionType);
//Since this player created the room, assign them the host value
playerData[socket.id].host = true;
playerData[socket.id].room = newRoom;
socket.join(newRoom);
io.sockets.to(newRoom).emit('Room Added', newRoom);
})
//Make the specified room a closed room
socket.on('Close the room', function (room) {
closeRoom(room);
})
socket.on('Room Availability', function (roomCode, questionType) {
if (!roomMap.get(roomCode)) {
socket.emit('Unavailable Room');
}
else {
//Check if the room has the question type the user chose
if (roomQuestionType.get(roomCode) == questionType) {
socket.emit('Available Room');
} else {
socket.emit('Unavailable Room');
}
}
})
socket.on('Open Room Availability', function (questionType) {
let roomFound = false;
for (let room of roomMap.keys()) {
if (!closedRoomsList.includes(room)) {
if (roomQuestionType.get(room) == questionType) {
roomFound = true;
socket.emit('Available Open Room', room);
}
}
}
if (roomFound == false) {
socket.emit('Unavailable Open Room');
}
})
socket.on('Join Room', function (values) {
//Give this player's 'name' variable a value
playerData[socket.id].name = values.p1;
//Give this player's 'room' variable a value
playerData[socket.id].room = values.p2;
//DELETE SOON: Checking the data before addition
console.log("Data in the room '" + values.p2 + "' before addition: ");
console.log(roomMap.get(values.p2));
//Put this player in the new room
socket.join(values.p2);
//Add the player's socketID and Name to the Room Map
let playersList = roomMap.get(values.p2);
playersList.push(values.p1);
//DELETE SOON: Checking the data after addition
console.log("Data in the room '" + values.p2 + "' after addition: ");
console.log(roomMap.get(values.p2));
io.sockets.to(values.p2).emit('Output Players', playersList);
if (playerData[socket.id].host == true) {
io.sockets.to(playerData[socket.id].room).emit('Current Host');
}
})
socket.on('Request Game Start', async function (room) {
//Checks if the user who started the game truly is the host
if (playerData[socket.id].host == false) {
return;
}
//Holds all the questions to be asked and their answers
gameSessionQuestions = await selectedQuestions(2, roomQuestionType.get(room));
//Reset the 'answered player' count
answeredPlayers.set(playerData[socket.id].room, 0);
io.sockets.to(room).emit('Game Start');
})
socket.on('Start Game Countdown', function () {
let pos = 0;
let countArr = ["2", "1", "Go"];
let counter = setInterval(function () {
//Update the count for all those in the room
io.sockets.to(playerData[socket.id].room).emit('Update Countdown', countArr[pos]);
if (pos == countArr.length) {
clearInterval(counter);
io.sockets.to(playerData[socket.id].room).emit('End Countdown');
currentQuestion = getQuestion(gameSessionQuestions[0], playerData[socket.id].room);
io.sockets.to(playerData[socket.id].room).emit('Receive Questions', currentQuestion);
//Holds the answer for the current question
currentQuestionAnswer = currentQuestionCorrectAnswer(gameSessionQuestions[0], playerData[socket.id].room);
//The answer to the question presented in this room is stored here
questionAnswers.set(playerData[socket.id].room, currentQuestionAnswer);
gameTimer = setTimeout(function () {
//Reveal if the players' answers are right or wrong
revealAnswer(answeredPlayers, playerData[socket.id].room);
//Start the countdown for the next question
countToNextQuestion(playerData[socket.id].room);
}, 21000)
} else {
pos++;
}
}, 1000);
})
socket.on('Answered Question', function (userAnswer, answeredPlayerUsername, timeAnswered) {
socket.broadcast.to(playerData[socket.id].room).emit('Display Answered Player', answeredPlayerUsername);
//DELETE SOON: Check the current question
console.log("Current Question's Answer: " + questionAnswers.get(playerData[socket.id].room));
console.log("Your answer: " + userAnswer);
let answerResult;
if (questionAnswers.get(playerData[socket.id].room) === userAnswer) {
answerResult = "btn-success";
//Add to the person's overall score
playerData[socket.id].score = addToScore(playerData[socket.id].score, timeAnswered);
socket.emit('Answer Check', answerResult);
}
else {
answerResult = "btn-danger";
socket.emit('Answer Check', answerResult);
}
//DELETE SOON: Checks the scores for the user
console.log("The score for '" + playerData[socket.id].name + "' is '" + playerData[socket.id].score + "'")
//Add 1 to the number of people who have answered in this room
answeredPlayers.set(playerData[socket.id].room, (answeredPlayers.get(playerData[socket.id].room)) + 1)
//DELETE SOON: Checks if the value is updating
console.log("Number of people who have answered: " + answeredPlayers.get(playerData[socket.id].room))
//If all users in the room have answered...
if (answeredPlayers.get(playerData[socket.id].room) == (roomMap.get(playerData[socket.id].room)).length) {
//DELETE SOON: Outputs message confirming all users answering
console.log("Everyone has answered");
//Stop the count
clearTimeout(gameTimer);
//Reveal if the players' answers are right or wrong
revealAnswer(answeredPlayers, playerData[socket.id].room);
//Start the countdown for the next question
countToNextQuestion(playerData[socket.id].room);
}
})
//Get the next question from the host
socket.on('Find Host', async function () {
if (playerData[socket.id].host == true) {
//DELETE SOON: Check the number of questions before
console.log('Question count before: ' + gameSessionQuestions.length)
gameSessionQuestions.shift();
//DELETE SOON: Check the number of questions after removing the one just asked
console.log('Question count after: ' + gameSessionQuestions.length)
//If there are still questions to be asked, send the next question and set the new correct answer
if (gameSessionQuestions.length != 0) {
//Get the next question and send it
currentQuestion = getQuestion(gameSessionQuestions[0], playerData[socket.id].room);
io.sockets.to(playerData[socket.id].room).emit('Receive Questions', currentQuestion);
//Get this question's correct answer
currentQuestionAnswer = currentQuestionCorrectAnswer(gameSessionQuestions[0], playerData[socket.id].room);
questionAnswers.set(playerData[socket.id].room, currentQuestionAnswer);
gameTimer = setTimeout(function () {
//Reveal if the players' answers are right or wrong
revealAnswer(answeredPlayers, playerData[socket.id].room);
//Start the countdown for the next question
countToNextQuestion(playerData[socket.id].room);
}, 21000)
} else {
//Holds the username and scores for all users in this room
let players_Scores = [];
let roomCode = playerData[socket.id].room;
let playerKeys = Object.keys(playerData);
for (let i = 0; i < playerKeys.length; i++) {
if (playerData[playerKeys[i]].room == roomCode) {
let scoreDetails = {
username: playerData[playerKeys[i]].name,
score: playerData[playerKeys[i]].score
}
players_Scores.push(scoreDetails)
await gameController.uploadScore(playerData[playerKeys[i]].name, playerData[playerKeys[i]].score, roomQuestionType.get(roomCode));
}
}
io.sockets.to(roomCode).emit('Show Scores', players_Scores);
}
}
})
//Remove details while reloading the menu page
socket.on('Back to Start', function () {
//Remove the player from the room in socketio
socket.leave(playerData[socket.id].room);
//If this is the host, delete the room
if (playerData[socket.id].host == true) {
roomMap.delete(playerData[socket.id].room);
roomQuestionType.delete(playerData[socket.id].room);
questionAnswers.delete(playerData[socket.id].room);
answeredPlayers.delete(playerData[socket.id].room);
}
//Remove this player's details
delete playerData[socket.id];
})
socket.on('disconnect', function () {
if (playerData[socket.id] && roomMap.get(playerData[socket.id].room) != undefined) {
//DELETE SOON: Check who left and from which room
console.log(playerData[socket.id].name + " has left the room '" + playerData[socket.id].room + "'");
//If on the lobby page, remove that player and update everyone's lists
let playerList = roomMap.get(playerData[socket.id].room);
playerList.splice(playerList.indexOf(playerData[socket.id].name), 1);
io.sockets.to(playerData[socket.id].room).emit('Output Players', playerList);
/*If this is the host,
* stop game timer
* alert all the players in the room,
* delete the room they were in*/
if (playerData[socket.id].host == true) {
clearTimeout(gameTimer);
socket.broadcast.to(playerData[socket.id].room).emit('Host Left');
roomMap.delete(playerData[socket.id].room);
roomQuestionType.delete(playerData[socket.id].room);
questionAnswers.delete(playerData[socket.id].room);
answeredPlayers.delete(playerData[socket.id].room);
}
delete playerData[socket.id];
}
})
})
好像是访问变量的时候出错,但是没有完整的代码,是不行的
你的问题用最少的代码来表示
let gameTimer;
let pos = 0;
let countArr = ["2", "1", "Go"];
let counter = setInterval(function () {
if (pos == countArr.length) {
console.log("Creating a new gameTimer", Date.now());
gameTimer = setTimeout(function () {
console.log('gameTimer executed')
}, 2100);
} else {
pos++;
}
}, 1000);
因此您的代码不断创建新的超时。以前的超时存在,它们不会被删除。
因此您需要在创建新游戏计时器之前删除 gameTimer,或者如果它已经是 运行
,则不要创建 gameTimerlet gameTimer;
let pos = 0;
let countArr = ["2", "1", "Go"];
let counter = setInterval(function () {
if (pos == countArr.length) {
if (gameTimer) return; // if gameTimer is defined, exit
console.log("Creating a new gameTimer", Date.now());
gameTimer = setTimeout(function () {
console.log('gameTimer executed')
}, 2100);
} else {
pos++;
}
}, 1000);