setTimeout против. Режим сна

Из того, что я понял в нескольких ответах SO, если компьютер переходит в спящий режим после вызова setTimeout, период ожидания следует игнорировать.

Например:

  • t0: setTimeout(foo, 30000);
  • t0+20s: компьютер переходит в спящий режим
  • t0+40s: компьютер выходит из спящего режима
  • t0+50s: foo вызывается

Но мои тесты показывают следующее поведение:

  • t0: setTimeout(foo, 30000);
  • t0+20s: компьютер переходит в спящий режим
  • t0+40s: компьютер выходит из спящего режима и вызывается foo

Насколько я понимаю, когда компьютер просыпается, если тайм-аут должен был быть активирован во время периода сна, он срабатывает мгновенно, в противном случае он срабатывает в t0+[значение тайм-аута].

Итак, каково ожидаемое поведение? Одинаково ли это во всех браузерах и ОС?

Один из моих тестов (с последней версией Chrome в Windows 10): https://codepen.io/robloche/pen/GRJvEJB


person Rodolphe    schedule 03.03.2020    source источник
comment
Общее определение setTimeout - это максимальное усилие как можно скорее после заданного тайм-аута. Поэтому было бы разумно, чтобы он срабатывал, как только компьютер снова просыпается. Я не уверен, что этот пограничный случай явно описан в спецификации, поэтому здесь каждая реализация может отличаться.   -  person deceze♦    schedule 03.03.2020
comment
Из того, что я могу собрать, setTimeout попытается соблюдать исходный период сна, если нет, он будет стоять в очереди на срабатывание. IOW: Если вы установили setTimeout на 1 минуту, перешли в спящий режим на 30 секунд, затем возобновите работу, через 30 секунд сработает тайм-аут, но если вы заснете на 2 минуты, тайм-аут сработает мгновенно при возобновлении.   -  person Keith    schedule 03.03.2020
comment
Это зависит от того, останавливаются ли часы, которые реализация использует для тайм-аута/спит, если компьютер переходит в спящий режим. Но на самом деле все текущие реализации используют фактическое время в качестве эталона для часов, используемых тайм-аутом, поэтому ваш второй пример является ожидаемым результатом. 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].?: да   -  person t.niese    schedule 03.03.2020
comment
@Keith Это то, что я заметил, но, похоже, это не соответствует тому, что я прочитал здесь: stackoverflow.com/questions/6346849/   -  person Rodolphe    schedule 03.03.2020
comment
@deceze Да, я знаю о поведении с максимальной отдачей, но даже зная это, есть огромная разница между учетом времени сна или его игнорированием.   -  person Rodolphe    schedule 03.03.2020
comment
Конечно, но 30000 в основном означает через 30 секунд, а не считать до 30, вычитая 1 каждую секунду, когда вы бодрствуете, поэтому наблюдаемое поведение имеет смысл.   -  person deceze♦    schedule 03.03.2020
comment
Верхний ответ для этих ссылок говорит -> the counter ticks on from the time the computer fell asleep, так что это говорит о том же.   -  person Keith    schedule 03.03.2020


Ответы (1)


Подводя итог комментариям выше:

  • Поведение, которое я описываю, кажется, имеет смысл для всех.
  • Я все еще не уверен, что это соответствует спецификациям или что все браузеры реализуют это таким образом.

Моя первоначальная проблема заключалась в обновлении токена аутентификации, и в итоге я нашел решение, которое не использует setTimeout (спасибо https://stackoverflow.com/a/6347336/603393):

  • Когда я получаю токен, я вычисляю и сохраняю дату следующего продления
  • Я использую setInterval, чтобы регулярно проверять дату следующего продления в прошлом.

Таким образом, не имеет значения, выйдет ли компьютер из спящего режима за 1 секунду до следующей даты обновления или через 36 часов после нее.

person Rodolphe    schedule 05.03.2020