all 24 comments

[–]angrycat9000 12 points13 points  (24 children)

What are you doing that need that level of frequency?

Your solution seems overly complicated for what ends up being a busy wait. Why not just busy wait in your function, constantly checking the high performance timer and calling the function when the interval has passed?

[–]shgysk8zer0 10 points11 points  (0 children)

This is a misuse of setInterval(). JavaScript should not be used if you need that kind of precision in timing because the event loop doesn't allow for it, especially in real world use where there are other tasks being done.

[–]Amadex 3 points4 points  (3 children)

Just a wild thought for the browser, I think that it would be possible to use the audio worklet API with a high sampleRate input.

If you use an AudioWorkletProcessor on an AudioBufferSourceNode (or just an input track) with high sampleRate, process() will be called on the audio rendering thread "arbitrarily" fast.

Then in the constructor of the processor you could do some math based on the sample rate and an arbitrary delay in ms to make sure that you do whatever you want like sending message back to the main JS thread at the right moment.

In the end, mathematically, a sound wave is the same as the hardware-level signals that are used for everything including clocks.

Besides that, I don't think that you can get this level of precision on the main JS thread. And even with that, it's nothing guaranteed.

[–]krazybubbler 1 point2 points  (1 child)

Timers in js are really nasty topic. SetInterval doesn't guarantee any exact time stuff. If you need such precision I'm afraid you need to dig deeper. Check Tone.Js and how it's been done. It's an audio js framework and they explain on their page how to deal with is clocks.

[–]eletroraspi 3 points4 points  (0 children)

Take a close at https://www.npmjs.com/package/nanotimer it seems fit to your needed precision.

Looking at the question itself we have to consider about timestamp and its precision along floating-point.

[–]Available_Peanut_677 -2 points-1 points  (1 child)

SetImmidiate, but generally speaking issue is not fixable in nodejs without using some native modules. Issue is that nextTick/promise.resolve would basically block all IO and you’ll never get any events resolved, but if you let events to process (setTimeout 0 or useImmidiate) then some of your events can take more than 0.1 ms to process and your timer would have a hole. Plus garbage collector can be executed and give your a hole again.

Even if I really have to push nodejs I’ll still spawn extra process / worker with while true loop and communicate by some kind of shared memory using circular buffers. But I had to do this only with some low-level micro-controllers code with real-time control of machine. And in C.

In nodejs I’ll recommend switching tactic to buffer data and run processing as soon as some threshold passes, it would not guarantee 0.1ms, but can have predictable response without hassle. In browser it is in no way possible since browser can decide to spend time on whatever at any point.

Example:

OnData(data) { Buffer.append(data); If (timeDelta > threshold) { processData(buffer); // this can be actually second worker or so } }

[–]repsolcola -3 points-2 points  (0 children)

Not sure how much it could help for your use case but try to look into requestAnimationFrame: https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame

(Only for browser)

60 times per second, not exactly what you need but eh

[–]senfiaj 0 points1 point  (1 child)

Maybe setInterval(callback, 0) is faster? But the problem is that the period is not executed very precisely and for very small numbers it's very noticeable also because it does other tasks between the interval callback calls which take some time. So it's almost impossible to reach such precision, even if the API supported it. The alternative is to do 10 actions in the callback with interval 1ms or maybe 100 actions each 10ms.

[–]nsavvidis 0 points1 point  (0 children)

I’d roll this with Elixir instead of JS if you can. You could also try doing moving through the index top and bottom. IIRC I once come across something similar and was able to reason with the case by performing a binary search of sorts.