Is there a more accurate way to create a Javascript timer than setTimeout?

后端 未结 16 2166
礼貌的吻别
礼貌的吻别 2020-11-22 14:11

Something that has always bugged me is how unpredictable the setTimeout() method in Javascript is.

In my experience, the timer is horribly inaccurate in

16条回答
  •  -上瘾入骨i
    2020-11-22 14:34

    Here are what I use. Since it's JavaScript, I will post both my Frontend and node.js solutions:

    For both, I use the same decimal rounding function that I highly recommend you keep at arms length because reasons:

    const round = (places, number) => +(Math.round(number + `e+${places}`) + `e-${places}`)
    

    places - Number of decimal places at which to round, this should be safe and should avoid any issues with floats (some numbers like 1.0000000000005~ can be problematic). I Spent time researching the best way to round decimals provided by high-resolution timers converted to milliseconds.

    that + symbol - It is a unary operator that converts an operand into a number, virtually identical to Number()

    Browser

    const start = performance.now()
    
    // I wonder how long this comment takes to parse
    
    const end = performance.now()
    
    const result = (end - start) + ' ms'
    
    const adjusted = round(2, result) // see above rounding function
    

    node.js

    // Start timer
    const startTimer = () => process.hrtime()
    
    // End timer
    const endTimer = (time) => {
        const diff = process.hrtime(time)
        const NS_PER_SEC = 1e9
        const result = (diff[0] * NS_PER_SEC + diff[1])
        const elapsed = Math.round((result * 0.0000010))
        return elapsed
    }
    
    // This end timer converts the number from nanoseconds into milliseconds;
    // you can find the nanosecond version if you need some seriously high-resolution timers.
    
    const start = startTimer()
    
    // I wonder how long this comment takes to parse
    
    const end = endTimer(start)
    
    console.log(end + ' ms')
    

提交回复
热议问题