Що відбувається з setTimeout, коли комп’ютер переходить у режим сну?


75

Припустимо, у сучасному веб-браузері я роблю setTimeout10 хвилин (о 12:00) і через 5 хвилин переводжу комп’ютер у режим сну, що має статися, коли система знову прокинеться? Що станеться, якщо він прокинеться до закінчення 10 хвилин (о 12:09) або набагато пізніше (о 16:00)?

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

Пояснення : Я не хочу використовувати файли cookie - я намагаюся створити тут веб-службу; і так, сервер відхилить старі та недійсні маркери.


1
Оскільки javascript - це сторона клієнта, чи не краще встановити файл cookie, який може закінчитися в певний час?
розбивач

stackoverflow.com/questions/3824754/… пропонує, як відповів Ендрю, що це не спрацює.
Сизиф

@daybreaker, Звичайно, файли cookie можливі, але я намагаюся створити сервісний додаток. Ці самі сервіси обслуговують веб-програму, програму iPhone та Android.
Судхір Джонатан

Відповіді:


61

Наскільки я тестував, він просто зупиняється і відновлюється після пробудження комп’ютера. Я припускаю, що це означає для сеансу, залежно від setTimeout/Intervalтикання лічильника з моменту, коли комп’ютер заснув.

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

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

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


1
Це також відповідає моєму досвіду.
jwl

Я щойно створив для цього швидкий тест. FF 30 і Chrome 35 роблять розумну роботу, запускаючи тривалий тайм-аут, як тільки комп’ютер відновлюється. IE 10 перезавантажує сторінку. Скрипка @ jsfiddle.net/Pegleg3941/8uhy8
EpicVoyage

the counter ticks on from the time the computer fell asleep.<- мій досвід також.
Ман

1
Станом на 2017 рік (Chrome 61) ця поведінка продовження лічильника від засинання не змінилася.
Ерез Коен,

6
Я думаю, це можна сформулювати чіткіше: коли комп’ютер прокидається, setInterval / setTimeout не знає, що минув будь-який час.
cdosborn

8

Порівняйте поточний час із датою та часом, коли сторінка була завантажена, приблизно так:

//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);

Це чудове рішення. Для мене працює дуже добре - дякую.
BeesonBison

У моєму випадку я повинен отримувати новий маркер лише в тому випадку, якщо користувач активний, а не простоював в останню годину. Отже, з маркера сервера, термін дії якого закінчується через 1 год, але перед цим я повинен отримати новий і оновити localStorage. Якщо користувач неактивний, покажіть повідомлення про закінчення терміну дії сеансу, інакше отримуйте новий маркер мовчки
CyberAbhay

У чому причина внутрішнього наборуInterval ()? Чому 5 секунд?
Робш

7

Ось мій код:

<!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

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

Найімовірніше, це те, що ОС відновиться з тим самим часом, що залишився на таймері, як і тоді, коли її було вимкнено. Інша можливість полягає в тому, що він взагалі не спрацює.

Якщо це насправді викликає занепокоєння, ви, мабуть, захочете бути в безпеці краще, ніж вибачити, і зберегти мітку часу, коли маркер був ініціалізований, і використовувати setIntervalдля періодичної перевірки (скажімо, двічі на хвилину).

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

[редагувати] Я згоден з іншим дописом, що він може негайно спрацювати при наступній галочці. Повідомлення в блозі Резіга дуже добре.


Сервер відмовиться від застарілого маркера ... Я намагаюся не показувати клієнту помилок без потреби ...
Судхір Джонатан

Ви насправді змусили мене думати, як у цьому випадку будуть поводитися мої власні програми ... це справді гарне запитання. Я майже хочу ввійти в свій банк і спробувати побачити, як вони поводяться.
Ендрю Куріозо,

Ймовірно, вони використовують файли cookie з позначкою часу. Тут я намагаюся працювати з послугами без файлів cookie, звідси питання.
Судхір Джонатан

Щодо редагування Ендрю: він може негайно спрацювати при пробудженні, але це залежить від браузера.
EpicVoyage

Наприклад, IE 10 перезавантажує сторінку.
EpicVoyage

4

На основі відповіді Бена я створив наступний утиліт. Ви можете налаштувати тривалість вибірки, однак я використовую її саме так для оновлення маркера:

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);

2

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

  1. Коли потік вільний і тайм-аут спрацьовує: таймер спрацьовує відразу після тайм-ауту. Це може мати певну точність приблизно 0-5 мс (типовий сценарій).
  2. Коли потік дуже зайнятий (величезний цикл), достатньо довгий, щоб пройти тайм-аут таймера: таймер буде запущений відразу після звільнення потоку.
  3. Коли є попередження: Така сама поведінка, як 2.
  4. Коли нитка призупинена, тому що наш ноутбук заснув: я бачив кілька речей. Але найпоширенішим є повна неточність та ігнорування часу, проведеного під час сну.

Оскільки таймери в JavaScript базуються на галочках процесора, а центральний процесор перебуває в режимі сну, тоді таймер повністю призупинений і відновлений як "оскільки нічого не могло б статися".


-2

У блозі Джона Резіга таймери, як кажуть, використовують "настінні годинники". Я вважаю, що події запускатимуться відразу після відновлення роботи машини, оскільки setTimeout () не гарантує виконання конкретного моменту часу, але якомога швидше після зазначеного інтервалу. Однак я сам це не перевіряв.


10
Вам слід було це перевірити - це не працює таким чином, і ваш висновок на основі блогу JR є дуже вільним. Це точно не відповідає настінним годинникам жодної системи, на якій я тестував.
jwl

2
FWIW, в специфікації сказано так: "зачекайте, поки документ, пов'язаний з контекстом методу, стане повністю активним протягом наступних таймаутів в мілісекундах ( не обов'язково послідовно )". Це означає, що таймер може бути призупинений під час сну комп’ютера.
geon 02
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.