So the purpose of the code is to import JSON questions and read them to the user in the terminal. The user gets 5 seconds to answer the question until the next question is displayed. The issue I am running into is that after the timer is triggered, the next question automatically times out even is the user enters an answer. Here is an example of my log:
Definition: A term used to describe a file or directory location on a drive 1. name 2. separator 3. path 4. prompt > Please answer within 5 seconds Definition: A term used to describe a file or directory location on a drive 1. name 2. separator 3. path 4. prompt > 3 Please answer within 5 seconds Definition: A term used to describe a file or directory location on a drive 1. name 2. separator 3. path 4. prompt > 3 Correct Complete: Score - 2/2
And here is my function:
async function vocabularyDrillMode() {
const definitions = loadJsonFile('definitions.json');
let score = 0;
const defBegin = definitions.length;
async function drillTerm(currentDefinition) {
console.log(`Definition: ${currentDefinition.definition}`);
currentDefinition.possibleTerms.forEach((term, index) => console.log(`${index + 1}. ${term}`));
return new Promise((resolve) => {
const timer = setTimeout(() => {
resolve({ success: false, term: "timeout" });
}, 5000);
rl.question(" > ", (userAnswer) => {
clearTimeout(timer);
const selectedAnswer = parseInt(userAnswer, 10) - 1;
// Check if the user entered 'q'
if (userAnswer.toLowerCase() === "q") {
resolve({ success: false, term: "q" });
} else if (!isNaN(selectedAnswer) && selectedAnswer >= 0 && selectedAnswer <= 3) {
// If user entered a valid numeric answer
resolve({ success: selectedAnswer === currentDefinition.correctDefinition, term: selectedAnswer });
} else {
// If user entered an invalid numeric answer or non-numeric input
resolve({ success: false, term: userAnswer });
}
});
});
}
let quitDrill = false;
while (definitions.length > 0 && !quitDrill) {
const randomIndex = Math.floor(Math.random() * definitions.length);
const currentDefinition = definitions[randomIndex];
const result = await drillTerm(currentDefinition);
if (result.success) {
score++;
definitions.splice(randomIndex, 1);
console.log("Correctn");
} else if (result.term === "q") {
quitDrill = true;
} else if (result.term === "timeout") {
console.log("Please answer within 5 seconds");
} else if (isNaN(result.term) || result.term > 3 || result.term < 0) {
console.log("Please enter a number 1-4 or 'q' to quit the program");
} else {
console.log("Incorrect.");
}
}
const statusMessage = quitDrill ? `Incomplete: User quit the drill. Score: ${score}/${defBegin}` : `Complete: Score - ${score}/${defBegin}`; console.log(`${statusMessage}`);
}
I have tried pausing and resuming the readline
and I have also tried reordering the console.log
of the question and terms to inside the promise and neither solved the issue.
2
Answers
You should use an abort signal to cancel the question when timeout, otherwise you will be answering the previous question after timeout.
The documentations shows how to timeout a question using the
signal
option.There is no need to use
setTimeout
.