質問

設定した場合に気づきました setTimeout 将来1分間、システム時間を過去に5分に変更してください。 setTimeout 関数は6分でトリガーされます。

これをやったのは、システムクロックに夏時間の変化中に何が起こるかを見たかったからです。

私のJavaScriptのWebページはaを使用します setTimeout 5秒ごとにページを自動的に更新するように機能し、夏時間の節約が発生した場合、ページ情報は1時間凍結します。回避策はありますか?

編集:Ajaxを使用してページを更新しています。ページ全体を更新したくありません。

役に立ちましたか?

解決

私がすることは、5秒ごとに新しいAjaxリクエストを開くことから変更することです 彗星 (長い投票)。サーバーが必要なときに新しい結果をブラウザにプッシュするため、これはより良いオプションです。これは、サーバー側で5秒ごとに、または新しい情報が利用可能になるたびにすることができます。

さらに良いことは、Webソケットを使用し、フォールバックとして彗星を持つことです。これは簡単に実装できます フェイ また socket.oi.

cometd o apeのような他のオプションがあります。

他のヒント

使用する setInterval それ以外の setTimeout そして、あなたの問題は解決する必要があります:)

アップデート:

settimeoutまたはsetIntervalのどちらかを実際に使用できない場合は、隠されてみることができます iframe これは、このようなものに見える単純なHTMLページをロードします。

<html>
    <head>
        <meta http-equiv="refresh" content="300"/>
        <script>
            document.domain='same as parent page';
            top.ajax_function_you_wish_to_trigger();
        </script>
    </head>
    <body>
    </body>
</html>

運が良ければ、メタの更新は同じ問題を引き起こすことはありません。

別の解決策は、イベントを介してサーバーに発砲することです サーバープッシュ. 。これを行わない理由はたくさんありますが、少なくともイベントを集中化してサーバーに負担をかけることはありませんが、最後の手段と見なされる可能性があります。

私は最近、この問題にも遭遇しました。私の場合、時間の変化は深刻な財政的な損失を引き起こす可能性があるため、私はそれを真剣に受け止めなければなりませんでした。

いくつかの背景:

  • IEとOperaはシステムの時間の変更を適切に処理します(SetimeOutへの副作用はありません、SetInterval)。
  • FF <4.0およびすべてのWebKitベースのブラウザは、過去への変化時間を処理できません(記述したとおり)。注:クロムのタイマーは、しばらく2〜60秒後にのみ停止します。

私の解決策:ユーザーインタラクション(Mousemove、マウスブなど)からのイベントを使用して、時間の変更チェックをトリガーします。

Clock.prototype.checkLocalTime = function(){
var diff = Date.now()- this.lastTimestamp;
if ( diff < 0 || diff > 20000) { // if time shifted back or more than 20s to the future
    console.warn('System time changed! By ' + diff + 'ms' );
    this.restartTimer();
    this.getServerTime();
}
this.lastTimestamp = time;

}

ご存知のように、タイマーを再起動し、サーバーと時間をさらに同期します。

これを行うには、メタタグの更新を使用できます。このコードは5秒ごとにページを更新します:

<meta http-equiv="refresh" content="5"> 

JavaScriptの質問に関しては、ブラウザがSettimeOutを処理する方法だけかもしれません。これにより、ブラウザは設定された時間にコードを実行するように指示し、その後、クロックが変更された場合、クロックが変更される前にコードがまだ実行されますか?ただ推測しますが、次回SettimeOutを使用するときはそのことを念頭に置かなければなりません。

編集:OK、Ajaxの編集では機能しません。これは本当に良い質問です。私が上で言ったように、SetimeOutが機能すると確信していますが、すごい、これは脳ティーザーです。

あなたはファッジして行うことができます if (Date in range foo) 小切手。基本的に、現在のタイムスタンプが夏時間から5秒以内にあるかどうかを確認し、使用するのではなくすぐにページを更新するだけです setTimeout.

このようにして、ユーザーは既知の時間の変更の近くでマイナーな迷惑を取得しますが、ページは1時間凍結しません。

使用していることがわかりました window.performance 私により正確な結果を与え、システムの時間が変わったときに物事を一貫性に保ちました。

これを使用して、現在の時間をSetInterval Tickの内側に入れて、カウントダウンタイマーがシステム時間の変更の影響を受けないようにしました。システムクロックを変更することにより、タイマーの不正行為を防止しようとするために、特定の時間からのダニの数に基づいて計算していました

getCurrentTime = () => {
  return window.performance ?
    performance.timing.navigationStart + performance.now() : Date.now();
}

tick() {
  let now = this.getCurrentTime();

  if (this.calibrateTime) { //calibrate with a given server time
    now -= this.timeCalibration;
  }

  const elapsedSeconds = (now - this.startedAt) / 1000;

  if (elapsedSeconds > this.props.timeLimit + this.props.submitBuffer) {
    clearInterval(this.interval);
    this.props.onTimeUp();
  }

  let secondsRemaining = this.props.timeLimit - Math.floor(elapsedSeconds);
  if (secondsRemaining < 0) secondsRemaining = 0;

}

startTimer() {
  if (!this.startedAt) {
    this.startedAt = Date.now();
  }

  this.setState({ started: true }, () => {
    this.interval = setInterval(this.tick.bind(this), 500);
  });
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top