0

so I have a node js / websocket server going, where I want to store multiple instances of setInterval timers...

I have them stored in an array of [timer, client] objects that I want to step through when a client disconnects, then step through the array and turn off all the timers that are paired with the disconnecting client before removing them from the array.

Removing the objects connected with the clients is working, however, the timers are not stopping...

I am declaring the timers like this -

clientSchedulePairs.push([setInterval(makeVisibleHandler, master_period, item, name), client]);

then trying to turn the schedule off like this when a client disconnects-

clearInterval(clientSchedulePairs[i][0]);

in my research i found this question -

clearInterval() is not stopping setInterval() - Firefox Extension Development

which says that I need to make a timer a global variable? but that isnt helping because if I have multiple timers for multiple clients how can i make them global variables?

I am storing them in a global const array that is declared globally such as-

const clientSchedulePairs = [];

however it is not working...

any idea on if the reason its not working is because its not declared as a global variable? or how I can get around this and get it to work? (i already tried declaring the schedule as a variable in my method before adding it to the array)

thanks.

UPDATED---

i got it working turning off the timers --- not sure if it had something to do with the way the client was disconnecting, after I removed my for loop into an external method that took in the client socket as a variable, then looped through my array of client / timer pairs and checked for the clients and removed them it started working. However, I am running into a kind of strange issue now...

as i said, i am looping through a clientTimerPairs array and checking if the client paired to that timer is === to the client_socket that was passed in from when the method was called when a client disconnects, in this loop, calls this--

clearInterval(clientTimerPairs[i].interval);

and the timers turn off, however I had a problem removing the client - timer tuples from the clientTimerPairs array now

i couldnt get them to remove from the array, so i changed it to work like this-

var indexToRemove = []; 

for (var i = 0; i < clientTimerPairs.length; i++) {
    if (clientTimerPairs[i].pairedClient === client_socket) {
        clearInterval(clientTimerPairs[i].interval);
        indexToRemove.push(i);
    }
 }

 for (var i = 0; i < indexToRemove.length; i++) {
    console.log('removing index ' + indexToRemove[i] + '...');
    clientSchedulePairs.splice(indexToRemove[i], 1);
}

however, even if i console print indexToRemove, and it has all index 0 - 6 in it, (because during testing i only connected 1 client with 6 timers), it should be stepping through clientTimerPairs and removing every single index so clientTimerPairs is empty, however, for some strange reason instead of going from 6 to 0 size, the array always ends up at 3 size!

even though it prints the removing index line 6 times and says it is removing index 0 - 5, 3 items are always left over in the clientTimerPairs array!

any idea why this might happen?

Chase
  • 267
  • 1
  • 6
  • 20

1 Answers1

1

That push statement does not provide a proper key-value pair. How about using es6 Map to secure actual pairs?

However, it should work as intended.

const timers = [];

for (let i = 0; i < 5; i++) {
    timers.push([setInterval(runTimer.bind({ id: i}), 100), i]);
}

function runTimer() {
    console.log(`running for id ${this.id}`);
}

setTimeout(() => {
    console.log('clearing timers')
    for (let i = 0; i < timers.length; i++) {
        clearInterval(timers[i][0]);
    }
}, 2000);

Edit regarding the addition to your post

The splicing does exactly as it is intended to do. Say you have an array of 6 elements. You are clearing elements from the array using an array of indices and remove the first element. That array length becomes 5. The second index points to the 6th element. When you try to splice the 6th element by its index, nothing happends. This is because you removed one element from the array, which made the 6th element shift to the 5th position.

A simple solution could be using es6 filter:

let items = ['one', 'two', 'three', 'four']; 
let indices = [1, 3]; 

items = items.filter((item, index) => indices.indexOf(index) === -1);

This returns an array with the first and third elements.

Shane
  • 3,049
  • 1
  • 17
  • 18
  • He's just pushing an array into another array, not a key value pair. – jered Jul 26 '17 at 20:37
  • 1
    @jered I suggested to use a key-value pair instead. At the moment he has to iterate over all connected clients, check if the second entry of the multidimensional array is set to the id of the disconnecting client and grab the first element of that same array and clear the interval. Using something like es6 Map is way faster then the array or using an object to store paired values for unknown keys (connected socket ids). – Shane Jul 26 '17 at 20:59
  • i changed it to a key value pair as you said as that is a better option but for some reason the clearInterval function still is not working for me...I literally even commented out all the array stuff and just went to where I declared the setInterval variable, and in the direct next line used clearInterval on that variable and the timer is still going-any idea why? – Chase Jul 27 '17 at 16:16
  • 1
    @Chase Can you show more of your code by updating your post, or enough to replicate the issue? It might help if you add which version of node you are using. – Shane Jul 27 '17 at 17:05
  • hey I actually got it to start turning the timers off, after i disconnect / close the browser window, the socket messages stop sending on the timers so the timers are turning off, however, i ran into a new problem where i cannot get all the timer/client pairs to remove from my clientTimerPair array for some reason, its pretty wierd, if you want to read whats going on i posted an updated response above. thanks for all the help. – Chase Jul 27 '17 at 18:09
  • @Chase I have updated my answer. It contained too many characters for a comment regarding your second issue. – Shane Jul 27 '17 at 19:13