2

I'm using the following code with a websocket to scrape data from a DB and return to users. It returns chat messages, users status and other things. The code works as expected (in testing) but I have a couple of questions.

                setInterval(async () => {
                    if (connectedUserIDs.length > 0) {
                        logger.info("short loop...")
                        await eventsHelper.extractEvents(db, connectedUserIDs, connectedSockets, ws)
                    }
                }, 5000)

Question 1. Will the SetInterval wait for the the "await" or will it just fire every 5 seconds? I assume it will fire every 5 seconds regardless.

If that is the case.

Question 2. Is there a way to repeat a task like above but ensure it only re-runs if the previous run as completed with a minimum time of 5 seconds? I want to avoid a situation where I get multiple queries running at the same time. Maybe the setInterval could be cancelled and restarted each time...

thankyou Adam

see sharper
  • 11,505
  • 8
  • 46
  • 65
Adam
  • 19,932
  • 36
  • 124
  • 207
  • 3
    The answer from @Fred Stark LGTM, but I would just comment that given you have websockets, this kind of polling loop should be unnecessary. It's much better to have the server push the changes as they occur, if at all possible (you may not have control fo what the server does of course). – see sharper Mar 17 '21 at 23:28
  • 1
    @seesharper that's a good point. Ideally you'd have a data store that your components recieve data from / listen to, and then on websocket events, run your framework's `setState` equivalent – coagmano Mar 18 '21 at 00:30
  • 1
    Does `eventsHelper.extractEvents()` actually return a promise that only resolves when its operation is done. If not, the answer you accepted will not accomplish your goal either. – jfriend00 Mar 18 '21 at 01:16
  • eventsHelper.extractEvents() scrapes a number of DB Tables for data that has changed in the last 15seconds and send to the relevant connection. Things like "added as favoriate", "chat message", "gifts sent to you" etc... (dating system)... This is only used to send data. All updates/inserts go via POST/GET calls to api and into DB... I hear you that websockets can be used in a different way to achieve an equal result and I'll do some research into that now... thankyou so much for all your help Stack Overflow!!! – Adam Mar 18 '21 at 04:52

1 Answers1

3

Question 1. Will the SetInterval wait for the the "await" or will it just fire every 5 seconds? I assume it will fire every 5 seconds regardless.

Yes it will naively re-run every 5s

Question 2. Is there a way to repeat a task like above but ensure it only re-runs if the previous run as completed with a minimum time of 5 seconds

Easiest way to prevent collisions is to set the next run after the await:

let timeoutId;
const extractEvents = async () => {
  if (connectedUserIDs.length > 0) {
    logger.info("short loop...");
    await eventsHelper.extractEvents(db, connectedUserIDs, connectedSockets, ws);
  }
  timeoutId = setTimeout(extractEvents, 5000);
};
timeoutId = setTimeout(extractEvents, 5000);

Storing timeoutId so you can clear it later

coagmano
  • 5,542
  • 1
  • 28
  • 41