1. ホーム
  2. javascript

[解決済み] javascriptで正確なタイマーを作成する方法は?

2022-03-02 07:28:52

質問

シンプルで正確なタイマーを作りたいのですが。

これは私のコードです。

var seconds = 0;
setInterval(function() {
timer.innerHTML = seconds++;
}, 1000);

ちょうど3600秒後に、約3500秒を印刷する。

  • なぜ正確ではないのでしょうか?

  • 正確なタイマーを作るにはどうしたらいいですか?

どのように解決するのですか?

<ブロッククオート

なぜ正確ではないのですか?

を使用しているからです。 setTimeout() または setInterval() . 信頼できない 正確性を保証するものではありません。 ラグが許される 任意に設定でき、一定のペースを保てるわけではありませんが 漂流しがち (ご観察の通り)です。

正確なタイマーを作るには?

を使用します。 Date オブジェクトの代わりに、ミリ秒単位の正確な現在時刻を取得します。そして、コールバックが何回実行されたかを数えるのではなく、現在の時刻の値に基づいてロジックを構築します。

単純なタイマーや時計の場合、時刻を記録する を明示する。

var start = Date.now();
setInterval(function() {
    var delta = Date.now() - start; // milliseconds elapsed since start
    …
    output(Math.floor(delta / 1000)); // in seconds
    // alternatively just show wall clock time:
    output(new Date().toUTCString());
}, 1000); // update about every second

さて、これには値が飛ぶ可能性があるという問題があります。間隔が少し遅れて、コールバックが 990 , 1993 , 2996 , 3999 , 5002 ミリ秒の場合、2回目のカウントが表示されます。 0 , 1 , 2 , 3 , 5 (!). そのため、このようなジャンプを避けるために、100msごとなど、より頻繁に更新することが望ましいでしょう。

しかし、時には、コールバックを実行する間隔を一定に保ちたい場合もあります。これにはもう少し高度な戦略(とコード)が必要ですが、その分利益は大きいです(タイムアウトも少なくなります)。このような場合は 自己調整 タイマーです。ここでは、繰り返されるタイムアウトのそれぞれの正確な遅延は、予想される間隔と比較して、実際に経過した時間に適応されます。

var interval = 1000; // ms
var expected = Date.now() + interval;
setTimeout(step, interval);
function step() {
    var dt = Date.now() - expected; // the drift (positive for overshooting)
    if (dt > interval) {
        // something really bad happened. Maybe the browser (tab) was inactive?
        // possibly special handling to avoid futile "catch up" run
    }
    … // do what is to be done

    expected += interval;
    setTimeout(step, Math.max(0, interval - dt)); // take into account drift
}