5

From what I understood in several SO answers, if a computer goes to sleep mode after a setTimeout has been called, the sleep period should be ignored.

For example:

  • t0: setTimeout(foo, 30000);
  • t0+20s: computer enters sleep mode
  • t0+40s: computer exits sleep mode
  • t0+50s: foo is called

But, my tests shows the following behavior:

  • t0: setTimeout(foo, 30000);
  • t0+20s: computer enters sleep mode
  • t0+40s: computer exits sleep mode and foo is called

My understanding is that when the computer wakes up, if the timeout would have been triggered during the sleep period, it's instantly triggered, otherwise, it's triggered at t0+[timeout value].

So what's the expected behavior? Is it the same across all browsers and OS?

One of my tests (with the latest version of Chrome on Windows 10): https://codepen.io/robloche/pen/GRJvEJB

Rodolphe
  • 1,689
  • 1
  • 15
  • 32
  • 1
    The general "definition" of `setTimeout` is "best effort as soon as possible after the given timeout". So it would make sense for it to trigger as soon as the computer wakes up again. I'm not sure whether this edge case is covered in the spec explicitly, so every implementation may differ here. – deceze Mar 03 '20 at 13:33
  • From what I can gather, setTimeout will try to honour the original sleep period, if not it will queue to fire. IOW: If you did a setTimeout of 1 min, went to sleep for 30 seconds, then resume, 30 seconds later the timeout will fire, But if you went to sleep for 2 mins, the timeout will fire instantly on resume. – Keith Mar 03 '20 at 13:35
  • It depends on if the clock the implementation uses for the timeout pauses/sleeps too if the computer goes to sleep. But afaik all current implementation use the actual time as a reference for the clock used by timeout, so your second example is the expected result. `My understanding is that when the computer wakes up, if the timeout would have been triggered during the sleep period, it's instantly triggered, otherwise, it's triggered at t0+[timeout value].?`: yes – t.niese Mar 03 '20 at 13:40
  • @Keith That's what I observed but it does not seem to follow what I read here: https://stackoverflow.com/questions/6346849/what-happens-to-settimeout-when-the-computer-goes-to-sleep – Rodolphe Mar 03 '20 at 13:42
  • @deceze Yes, I'm aware of the "best effort" behaviour but even knowing that, there's a huge difference between taking into account the sleep time or ignoring it. – Rodolphe Mar 03 '20 at 13:43
  • 1
    Sure, but "`30000`" basically means *"in 30 seconds"*, not "count down to 30 by subtracting 1 each second you're awake", so the observed behaviour makes perfect sense. – deceze Mar 03 '20 at 13:46
  • The top answer for that links says -> `the counter ticks on from the time the computer fell asleep`, So that's saying the same thing. – Keith Mar 03 '20 at 13:49

1 Answers1

2

To sum up the comments above:

  • The behavior I describe seems to make sense for everyone.
  • I'm still not sure that meets the specs or that all browsers implement it this way.

My initial problem being the renewal of an authentication token, I ended up with a solution that doesn't use setTimeout (thanks to https://stackoverflow.com/a/6347336/603393):

  • When I get a token, I compute and store the next renewal date
  • I use setInterval to regularly check next renewal date is in the past.

This way, it doesn't matter if the computer wakes up 1 second before the next renewal date or 36 hours after.

Rodolphe
  • 1,689
  • 1
  • 15
  • 32