Javascript setTimeout unexpected output

I worked with scripts using the setInterval (fn, delay) function in my application, and after reading about how setTimeout and JS work, I come across some strange results, so I did a test: Here is jsfiddle https://jsfiddle.net / jyq46uu1 / 2 /

And the code as suggested:

var limit = 1000000000; var intervals = 0; var totalTime = new Date(); var startTime = new Date(); var uid = setInterval( function () { // final lap? if (intervals == 9) clearInterval(uid); for (i = 0; i < limit; i += 1) { // just working the CPU } // reduce the iterations limit = limit / 10; intervals += 1; console.log('Interval ' + intervals +' Time elapsed : ' + (new Date() - startTime)); // reset the time startTime = new Date(); }, 250, 9); 

Well, from the fact that I'm blushing from http://ejohn.org/blog/how-javascript-timers-work/ Javascript makes the timer call the function in setInterval even if the "thread is blocked", so if the function is still making a call only in the queue and so on and so forth .... in my notebook this code produces the following:

 "Interval 1 Time elapsed : 4264" "Interval 2 Time elapsed : 477" "Interval 3 Time elapsed : 91" "Interval 4 Time elapsed : 170" "Interval 5 Time elapsed : 246" "Interval 6 Time elapsed : 242" "Interval 7 Time elapsed : 248" "Interval 8 Time elapsed : 248" "Interval 9 Time elapsed : 248" 

Itโ€™s good if the fact that I have red is true, by the end of the first interval, all function calls were in the queue ... in my script, I cut the work for each execution, so each call should take less seconds than the previous one, BUT regardless of how many iterations I set, the elapsed time always selects the interval after the 4th run. Maybe I was wrong, but if by 4264 all functions are already in the queue and are supposed to start immediately, they should show less time, right? ... if the 3rd iteration displays 91, and the rest are behind them, they should take 91 or less. But this is not so.

If you understand what is going on, explain it to me because I think something is missing.

+7
javascript timer settimeout
source share
3 answers

I think the first time is not calculated from the start interval in the queue, but from where you set startTime.

Then the first timer counts the initialization time, the creation of the environment, the distribution of variables and timers.

Try this modification:

 var limit = 1000000000; var intervals = 0; var totalTime = new Date(); var startTime = false; var uid = setInterval( function () { if (!startTime) startTime = new Date(); // final lap? if (intervals == 9) clearInterval(uid); for (i = 0; i < limit; i += 1) { // just working the CPU } // reduce the iterations limit = limit / 10; intervals += 1; console.log('Interval ' + intervals +' Time elapsed : ' + (new Date() - startTime)); // reset the time startTime = new Date(); }, 250, 9); 

In addition, the first time takes longer because the function is interpreted, then the subsequent times are executed by the โ€œcompiledโ€ / optimized Javascript JIT (see https://en.wikipedia.org/wiki/Just-in-time_compilation ). Check this code to see the proof.

 var limit = 1000000000; var intervals = 0; var totalTime = new Date(); var startTime = new Date(); var uid = setInterval( function () { startTime = new Date(); // final lap? if (intervals == 9) clearInterval(uid); for (i = 0; i < limit; i += 1) { // just working the CPU } // reduce the iterations limit = limit / 10; intervals += 1; console.log('Interval ' + intervals +' Time elapsed : ' + (new Date() - startTime)); // reset the time startTime = new Date(); }, 250, 9); 

output:

 Interval 1 Time elapsed : 3249 Interval 2 Time elapsed : 299 Interval 3 Time elapsed : 31 Interval 4 Time elapsed : 5 Interval 5 Time elapsed : 0 Interval 6 Time elapsed : 0 Interval 7 Time elapsed : 0 Interval 8 Time elapsed : 0 Interval 9 Time elapsed : 0 Interval 10 Time elapsed : 0 

setInterval is not suitable for measuring the time during which it should queue the next execution. I think this is due to sleep () ing. This is unreliable if the process accepts the processor and hangs it (as for you).

setInterval guarantees only the following:

  • Run number 1 will not execute in less than 250 ms.
  • Execution number 2 will not occur less than 2 * 250 m ahead.
  • Run number 3 will not happen in less than 3 * 250 m.
  • ...

setInterval does not guarantee that any execution will occur before a certain time in the future. It depends on the current CPU usage.

The queue and the start of functions in the queue also depend on the current CPU usage.

Additional General Tips If you need to perform a function periodically, I recommend this approach, which guarantees a delay that always exceeds 250 ms between execution

 var t = false; var fun = function() { console.log("run"); t = setTimeout(fun, 250); } fun(); 
+1
source share

I am not sure that I am right, and that is what I know about "Javascript".

Javascript is event-driven, and there is no โ€œqueue and wait." It will just go in parallel (something like threads).

I think it will make sense how quickly he interprets and accepts the next.

0
source share

Well, I have a few questions to talk about, first look at the results.

Results Image

"New" code:

 var limit = 1000000000; var intervals = 0; var totalTime = new Date(); top.uid = setInterval( function () { startTime = new Date(); // final lap? if (intervals == 9) clearInterval(top.uid); for (i = 0; i < limit; i += 1) { // just working the CPU } // reduce the iterations limit = limit / 10; intervals += 1; console.log('Interval ' + intervals +' Time elapsed : ' + (new Date() - startTime)); // reset the time }, 1); 

Note that I remove the startTime variable from line 4 and pass it to the beginning of the function, so the calculated time is the same for all calls. I changed the TIMER 250ms form to 1 ms, so you do not need to calculate -250 ms from each result.

The new results are quite consistent and show that the time trace for the calculation is very clear and consistent.

Hope I helped sort it out.

0
source share

All Articles