Что происходит с setTimeout, когда компьютер переспал?

В современном веб-браузере предположим, что я делаю setTimeout в течение 10 минут (в 12:00), а через 5 минут переведите компьютер в режим сна, что должно произойти, когда система снова проснется? Что произойдет, если он просыпается до 10 минут (в 12:09) или намного позже (в 16:00)?

Причина, по которой я спрашиваю, заключается в том, что я хочу, чтобы новый токен аутентификации запрашивался каждые 10 минут, и я не уверен, что браузер сделает все правильно и сразу же запросит новый токен, если он просыпается после долгого времени.

Разъяснения. Я не хочу использовать файлы cookie. Я пытаюсь создать здесь веб-сервис; и да, сервер отклонит старые и недействительные токены.

Ответ 1

Насколько я тестировал, он просто останавливается и возобновляется после того, как компьютер просыпается. Я полагаю, что это означает, что для сеанса в зависимости от setTimeout/Interval счетчик зацикливается с момента, когда компьютер засыпает.

Я не думаю, что вы должны полагаться на точность setTimeout/Interval для критически важных вещей. Для google chrome я недавно обнаружено, что любой тайм-аут/интервал (который меньше 1 с) будет замедляться до одной секунды, если вкладка, в которой она активирована, теряет фокус.

Кроме того, точность тайм-аутов/интервалов зависит от запуска других функций и т.д. Короче: это не очень точно.

Таким образом, использование интервалов и тайм-аутов, проверка времени на время начала в рамках функции, начатой ​​им, даст вам лучшую точность. Теперь, если вы начнете в 12:00, компьютер отправится спать и просыпается в 16:13 или около того, проверяя 16:13 против 12:00, вы уверены, что вам нужно обновить токен. Пример использования сравнения времени можно найти здесь

Ответ 2

Поведение основано как на браузере, так и на операционной системе. ОС справляется со сном, и отдельные приложения часто не учитывают его.

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

Если это действительно вызывает беспокойство, вы, вероятно, захотите быть более безопасным, чем извините, и сохраните отметку времени, когда токен был инициализирован, и используйте setInterval, чтобы периодически проверять его (скажем, два раза в минуту).

Однако безопасность не должна быть просто частью клиентской стороны. Убедитесь, что ваш сервер выдает ошибку, если используется старый/недопустимый токен и что Ajax ведет себя соответственно в ответ.

[править] Я согласен с другим сообщением, что он может немедленно сработать на следующем тике. Сообщение в блоге Resig очень хорошее.

Ответ 3

Сравните текущее время datetime с datetime, когда страница была загружена, например:

//Force refresh after x minutes.
var initialTime = new Date();
var checkSessionTimeout = function () {
    var minutes = Math.abs((initialTime - new Date()) / 1000 / 60);
    if (minutes > 20) {
        setInterval(function () { location.href = 'Audit.aspx' }, 5000)
    } 
};
setInterval(checkSessionTimeout, 1000);

Ответ 4

Вот мой код:

<!doctype html>
<html>

<body>
<input type="button" name="clickMe" id="colourButton" value="Start Timer" onclick="setTimeout('alert(\'Surprise!\')', 120000)"/>

</body>
<script>


</script>
</html>

Я взял три сценария, которые могли бы ответить на вопрос.

Сценарий 1:. Через 00 секунд нажмите кнопку "Старт таймера" . Через 25 секунд компьютер засыпает. Через 1 минуту 40 секунд просыпается компьютер. При отображении оповещения на 2 минуты отображается.

Сценарий 2:. Через 00 секунд нажмите кнопку "Старт таймера" . Через 26 секунд компьютер засыпает. Через 3 минуты я провожу компьютер. Отобразится предупреждение.

Сценарий 3: Это действительно поразительно.

<input type="button" name="clickMe" id="colourButton" value="Start Timer" onclick="setTimeout('alert(\'Surprise!\')', 600000)"/>

В 00 секунд я нажимаю кнопку "Старт таймера" . Примерно через 1 минуту 30 секунд компьютер переходит в спящий режим (мой компьютер занимает минуту, чтобы инициировать спящий режим).

В 8 минут я включаю ноутбук. В 10 минут точно появляется предупреждение.

PS: This is my first ever comment on Stack Exchange. I prefer to execute code and view results rather than infer from theory.

Ответ 5

Поведение таймеров JavaScript (setTimeout) в нескольких сценариях.

  • Когда поток свободен и срабатывает тайм-аут: таймер запускается сразу после таймаута. Это может иметь определенную неточность около 0-5 мс (типичный сценарий).
  • Когда поток очень занят (огромный цикл) достаточно долго, чтобы передать тайм-аут таймера: таймер будет выполняться сразу же после освобождения потока.
  • Когда появляется предупреждение: такое же поведение, как и 2.
  • Когда поток приостановлен, потому что наш ноутбук заснул: я видел несколько вещей. Но наиболее распространенной является полная неточность и игнорирование времени, проведенного во время сна.

Поскольку таймеры в JavaScript основаны на тиках ЦП, а процессор спящий, таймер полностью приостанавливается и возобновляется как "так как ничего не случилось бы".

Ответ 6

На основании ответа Бена я создал следующую утилиту. Вы можете настроить продолжительность выборки, но я использую ее так же, как это для обновления токена:

const absoluteSetInterval = (handler, timeout) => {
  let baseTime = Date.now();
  const callHandler = () => {
    if (Date.now() - baseTime > timeout) {
      baseTime = Date.now();
      handler();
    }
  };
  return window.setInterval(callHandler, 1000);
};

const absoluteClearInterval = (handle) => window.clearInterval(handle);

Ответ 7

В John Resig blog таймеры, как говорят, используют "настенные часы". Я считаю, что события будут срабатывать сразу же после возобновления работы машины, потому что setTimeout() не гарантирует, что выполнение является конкретным моментом времени, но как можно скорее после указанного интервала. Тем не менее, я не проверил его сам.