Home >Web Front-end >JS Tutorial >Why Are JavaScript's `setTimeout()` and `setInterval()` Inaccurate, and How Can I Create a More Precise Timer?

Why Are JavaScript's `setTimeout()` and `setInterval()` Inaccurate, and How Can I Create a More Precise Timer?

Patricia Arquette
Patricia ArquetteOriginal
2024-12-13 14:52:12550browse

Why Are JavaScript's `setTimeout()` and `setInterval()` Inaccurate, and How Can I Create a More Precise Timer?

Accurate JavaScript Timer: An Analysis

Many developers commonly employ the setTimeout() or setInterval() methods to create timers. However, these methods lack accuracy guarantees. They may experience arbitrary lags, drifting from their intended pace.

Inaccuracy Causes

The inherent issue stems from the mechanism used by setTimeout() and setInterval(). These functions rely on the browser's event loop, which is not guaranteed to execute at consistent intervals. The actual execution time can vary based on the browser load, system resources, and other factors.

Creating Accurate Timers

To address this issue, developers should instead leverage the Date object to obtain accurate (millisecond-precise) timestamps. Subsequently, they should base their logic on the current time value rather than relying on execution count.

For simple timers or clocks, maintaining the time difference explicitly is a viable approach:

var start = Date.now();
setInterval(function() {
    var delta = Date.now() - start; // milliseconds elapsed since start
    // ...
    // Output in seconds
    console.log(Math.floor(delta / 1000));
}, 1000);

However, this technique can lead to jumpy values due to potential lags in the interval execution. To mitigate this, developers may consider updating the interval more frequently, such as every 100ms.

Advanced Techniques: Self-Adjusting Timers

For steadfast intervals without drift, self-adjusting timers offer an advanced solution. These timers dynamically adjust the delay between subsequent execution based on the actual elapsed time:

var interval = 1000; // ms
var expected = Date.now() + interval;
setTimeout(step, interval);
function step() {
    var dt = Date.now() - expected; // drift
    if (dt > interval) {
        // Handling severe drift here
    }
    // ... Perform desired action

    expected += interval;
    setTimeout(step, Math.max(0, interval - dt)); // Adjust delay to correct for drift
}

The above is the detailed content of Why Are JavaScript's `setTimeout()` and `setInterval()` Inaccurate, and How Can I Create a More Precise Timer?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn