I'm creating timeouts with setTimeout and storing them in to an array of objects with the following code in Node.js:
actionSensorTimers = [];
/* -------------- OTHER CODE -----------------*/
let delay = (actionStep.delay !== undefined) ? actionStep.delay : 0;
let timeout = {
name: name,
timeout: setTimeout(async function() {
url += properties.join('&');
await request(url, function(err, res, body) {});
let previousState = {
...targetIotControlPoint,
previousState: undefined
}
await iotConn.query('UPDATE ' + actionStep.type + 's SET previousState = ?'
+ ' WHERE name = ?', [JSON.stringify(previousState), targetIotControlPoint.name]);
}, delay)
}
actionSensorTimers.push(timeout);
And that code works perfectly: The callback gets successfully fired after the delay, the request is made and database updated. However, when I try to cancel the setTimeout with the following code, it still gets fired after the delay.
let found = actionSensorTimers.find(timer => timer.name == name);
if (found !== undefined) {
console.log(found);
clearTimeout(found.timeout);
actionSensorTimers = actionSensorTimers.filter(timer => timer.name != name);
}
The Array.find() successfully finds the object and logs the object on the console (see image below), but the timeout doesn't get cancelled.
The problem shouldn't be in the scope while accessing the actionSensorTimers[n].timeout, because the Array.find() finds the right object and logs it successfully.
Thanks already for any help!
Okay it turned out that the problem was lying in my loop where the setTimeout code was in. I was pushing two timeout-objects to the array with an identical name-value but different timeouts. This caused my finding-system to return me the FIRST element in the array which's name matched.
Since the timeout I wanted to cancel was the second one, I never got the right reference and was always trying to cancel the wrong timeout which had already been run. (See in the image it says _called: true
)
I have now added a check to prevent two timers with the same name-parameter to get into my array of objects.