web-dev-qa-db-ja.com

コンピューターがスリープ状態になると、setTimeoutはどうなりますか?

最近のWebブラウザーで、10分間(12:00)にsetTimeoutを実行し、5分後にコンピューターをスリープ状態にすると、システムが再びウェイクアップするとどうなりますか? 10分が経過する前に(12:09に)、またはそれよりかなり後に(16:00に)ウェイクアップするとどうなりますか?

私が尋ねている理由は、10分ごとに新しい認証トークンをリクエストしてもらいたいためです。ブラウザーが正しいことを実行するかどうかわからないので、しばらくして目覚めるとすぐに新しいトークンをリクエストします時間。

説明:Cookieを使用したくない-ここでWebサービスを構築しようとしています。はい、サーバーは古い無効なトークンを拒否します。

63
Sudhir Jonathan

私がテストした限りでは、コンピュータが起動した後に停止して再開します。これは、セッションがsetTimeout/Intervalに依存することを意味し、コンピューターがスリープ状態になったときからカウンターが作動します。

タイムクリティカルなものについては、setTimeout/Intervalの精度に依存すべきではないと思います。 google chrome I 最近発見されました の場合、アクティブ化されているタブがフォーカスを失うと、タイムアウト/間隔(1秒より短い)が1秒に1回遅くなります。

それとは別に、タイムアウト/間隔の精度は、実行中の他の関数などに依存します。要するに、あまり正確ではありません。

したがって、間隔とタイムアウトを使用して、それによって開始された関数内の開始時間に対して時間をチェックすると、精度が向上します。これで、12:00に開始すると、コンピューターはスリープ状態になり、16:13程度にウェイクアップします。16:13を12:00と比較して確認すると、トークンを更新する必要があります。時間比較の使用例は次のとおりです here

46
KooiInc

次のように、現在の日時とページが読み込まれた日時を比較します。

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

この動作は、ブラウザとオペレーティングシステムの両方に基づいています。 OSはスリープを処理し、個々のアプリはそれを考慮しません。

最も可能性が高いのは、OSがシャットダウンしたときと同じタイマーの残り時間で復帰することです。もう1つの可能性は、まったく起動しないことです。

本当に心配な場合は、トークンが初期化されたときのタイムスタンプを申し訳ありませんが保存し、setIntervalを使用して定期的に(たとえば、1分に2回)確認することをお勧めします。

ただし、セキュリティはクライアント側だけのものではありません。古い/無効なトークンが使用されている場合はサーバーがエラーをスローし、Ajaxが適切に動作することを確認してください。

[編集]次のティックですぐに発火するかもしれないという他の投稿に同意します。 Resigのブログ投稿はとても良いです。

4
Andrew Curioso

これが私のコードです:

<!doctype html>
<html>

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

</body>
<script>


</script>
</html>

この質問に答える可能性のある3つのシナリオを取り上げました。

シナリオ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秒で、コンピューターは休止状態モードになります(私のPCは休止状態を開始するのに1分かかります)

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.
3
DannyBoi

ベンの答えに基づいて、次のユーティリティを作成しました。サンプリング期間を微調整できますが、トークンの更新に次のように使用します。

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
Erez Cohen

いくつかのシナリオでのJavaScriptタイマーの動作(setTimeout)。

  1. スレッドが解放されてタイムアウトが発生した場合:タイマーはタイムアウトの直後に発生します。約0〜5 msの不正確さがある場合があります(一般的なシナリオ)。
  2. スレッドが非常にビジー(巨大なループ)で、タイマータイムアウトを渡すのに十分な時間の場合:タイマーは、スレッドが解放された直後に実行されます。
  3. アラートが発生した場合:2と同じ動作。
  4. ラップトップがスリープ状態になったためにスレッドが一時停止したとき:私はいくつかのことを見てきました。しかし、最も一般的なのは、完全に不正確であり、睡眠中に費やされた時間を無視することです。

JavaScriptのタイマーはCPUティックに基づいており、CPUはスリープしているため、タイマーは完全に一時停止され、「何も起こらなかったため」再開されます。

2
José Cabo