Webster Webster - 17 days ago 4
Javascript Question

Node JS - clearTimeout from previous instance or state

I'm working on a telegram bot project that has a lot to do with setTimeout. And currently my problem is, I can't clear the timeout, even if i already put it on

module.exports
.

Here's my previous question.

The problem is, whenever I clear the timeout, it does nothing. The timeout still goes on.

Here's my code to create the timeout

var createSingleton = require('create-singleton');

var p3 = createSingleton(function mySingleton() {
service.canceledTimeout(res,bot)
});

var myInstance3 = new p3();


I got a module called promises

module.exports.timeouts = []; //general.timeouts


And i put the setTimeout object to that module

canceledTimeout = function(res,bot) {
return general.timeouts.push(setTimeout(function () {
return updateState(general.THIRTY_SECONDS_REMAINING_CHECK_STATE, res)
.then (function(msg) {
if (msg !== null) {
return bot.sendMessage(res.chat.id, msg, general.baseFormat())
.then (function(x) {

setTimeout(function () {
updateState(general.TIMEOUT, res)
.then (function(msg) {
if (msg !== null) {
return bot.sendMessage(res.chat.id, msg, general.baseFormat());
}
});
},30000);

});
}
});
},90000));
}


Whenever the game/room is finished, I call this function.

clearTimeout(general.timeouts);


But, after the player created a room again, the timeout still runs.

I think the problem is the timeout is not being cleared. That's from my point of view.

Any thought or help will be appreciated guys.
Thanks

Answer

I see at least two issues:

  1. There are two setTimeout calls there, and you're not remembering the handle of one of them. If you don't want to cancel that second 30-second timer, that's fine, but I thought I should call it out.

  2. clearTimeout accepts a single timer handle, but you're passing it an array here:

    clearTimeout(general.timeouts);
    

    Instead, you need to clear them individually:

    general.timeouts.forEach(function(handle) { clearTimeout(handle) });
    

    (Subject to testing that the extra args it receives don't bother it, you may be able to shorten that to general.timeouts.forEach(clearTimeout);. But again, forEach calls its callback with three args, not just one, so be sure to test before using that.)