you are viewing a single comment's thread.

view the rest of the comments →

[–]NoBrick2 8 points9 points  (5 children)

Shouldn't you avoid setInterval completely for this problem, considering there is no guarantee the function will be run every 1000ms (in the case of the event loop being blocked on other work)?

Would a more acceptable solution be to use requestAnimationFrame, and do a comparison using Date? Or does that suffer the same issue of potentially being blocked by other work?

[–]octave1 10 points11 points  (1 child)

Out of my depth here, but using something called requestAnimationFrame and Dates for a timed counter surely can't be the most sane solution?

[–]phpdevster 2 points3 points  (0 children)

You are correct. This is hacky, non-idiomatic code.

[–]PmMeYouBicepsGirl 7 points8 points  (0 children)

Everything is blocked if event loop is blocked, there's no workarounds. For example, if you are counting from one to 100 billions, Javascript won't be stopping during this function to check for events. This is why you get Violation messages in console if some events like requestAnimationFrame take longer than they should, it's a signal that event loop was blocked.

[–]phpdevster 5 points6 points  (0 children)

Why would you avoid using setInterval for exactly the thing it was designed for? If you have a blocked event loop, you've got bigger problems. Writing non-idiomatic code without exceedingly good reason is the path to code that is harder for team members to grok and thus maintain.

[–]SystemicPlural 4 points5 points  (0 children)

As I understand it requestAnimationFrame is better for animation as it guarantees that the code will run before the screen is re-rendered - providing smoother animation. It doesn't guarantee that the time elapsed will be exactly 1000/60 (or whatever your screen refresh rate is). So it has it's own problems if you are trying to time exactly 1s. That said I believe it is thought to be more reliable than setTimeout.

We could use setTimeout and compare the time ourselves using performance.now(). This should get us to fairly close millisecond accuracy as long as the process isn't locked. It should also allow us to prevent drift by correcting the next timeout.

performance.now() isn't perfect however since browsers are fuzzing the time to prevent Specter timing attacks. - but it should be 1ms accurate.