0

Take this function for example:

function mySlowFunction(baseNumber) {
    console.time('mySlowFunction');
    var result = 0; 
    for (var i = Math.pow(baseNumber, 10); i >= 0; i--) {       
        result += Math.atan(i) * Math.tan(i);
    };
    console.timeEnd('mySlowFunction');
    return result;
}

This is a very CPU-intensive function. It takes around 3 seconds to complete for mySlowFunction(5).

Now consider this code:

setInterval(() => console.log("interval"), 1000); 
mySlowFunction(5);

I expect it to log "interval" every second, but I understand that since mySlowFunction is running on the thread and JS is single-threaded, the callback for setInterval is executed only after mySlowFunction completes.

Is there any way I can ensure the callback is called on the specified interval? I want this in a browser-based environment.

Saravana
  • 37,852
  • 18
  • 100
  • 108
  • 1
    You simply shouldn't be blocking the main thread with anything for several seconds. If you have some intensive calculations to do, put them in a web worker or break them up into interruptible chunks with `setTimeout`. – deceze Jul 21 '17 at 13:22
  • I don't believe you can be sure of that, precisely for the reason you stated : JS is single-threaded. I don't think there's a way around this. – Jeremy Thille Jul 21 '17 at 13:23

2 Answers2

1

You shouldn't expect the interval to fire at the specified delay.
Here -> ( Reasons for delays longer than specified ) are a couple of reasons why the delay may take longer than expected. Anyway, if you still want to ensure that your interval will fire before your mySlowFunction finished execution you can as mentioned in the comments use a Worker

The Worker interface of the Web Workers API represents a background task that can be easily created and can send messages back to its creator.

to allocate the computation of mySlowFunction to a different thread.

Here is an example:

var blobWorker = URL.createObjectURL( new Blob([ '(',
    function() {
        self.onmessage = function(e) {
          
         var result = 0; 
         for (var i = Math.pow(e.data, 10); i >= 0; i--) {
            result += Math.atan(i) * Math.tan(i);
         };
         
          self.postMessage(result);
        };
    }.toString(),
')()' ], { type: 'application/javascript' } ) );

var worker = new Worker( blobWorker );

worker.onmessage = function(e) {

    console.log("result from mySlowWorker:", e.data);
}

var intervalId = setInterval(() => console.log("interval"), 1000);

worker.postMessage(5);

URL.revokeObjectURL( blobWorker );

setTimeout( _ => { clearInterval(intervalId); console.log('done') }, 5000)
DavidDomain
  • 14,976
  • 4
  • 42
  • 50
0

Timer delay is not guaranteed in Javascript. Asynchronous events such as timers and mouse clicks are executed one at a time, due to Javascript's single threaded nature.

Eduardo Melo
  • 481
  • 1
  • 6
  • 19