Lecture
setTimeout
clearTimeout
setInterval
setTimeout
with NFE setInterval
setTimeout
setTimeout(func, 0)
Almost all implementations of JavaScript have an internal timer scheduler that allows you to set a function call after a specified period of time.
In particular, this feature is supported in browsers and in the Node.JS server.
setTimeout
Syntax:
var timerId = setTimeout(func/code, delay[, arg1, arg2...]) |
Options:
func/code
delay
arg1
, arg2
... The function will be executed after the time specified in the delay
parameter.
For example, the following code will trigger an alert('Привет')
in one second:
1 | function func() { |
2 | alert( 'Привет' ); |
3 | } |
4 | setTimeout(func, 1000); |
If the first argument is a string, the interpreter creates an anonymous function from this string.
That is, such a record works in the same way:
1 | setTimeout( "alert('Привет')" , 1000); |
The use of strings is not recommended, as they can cause problems when minimizing code, and, in general, the very possibility of using a string is retained only for compatibility.
Instead, use anonymous functions:
1 | setTimeout( function () { alert( 'Привет' ) }, 1000); |
clearTimeout
The setTimeout
function returns a timerId
that can be used to cancel an action.
Syntax: clearTimeout(timerId)
.
In the following example, we set a timeout and then delete (change your mind). As a result, nothing happens.
1 | var timerId = setTimeout( function () { alert(1) }, 1000); |
2 |
3 | clearTimeout(timerId); |
setInterval
The setInterval
method has a syntax similar to setTimeout
.
var timerId = setInterval(func/code, delay[, arg1, arg2...]) |
The meaning of the arguments is the same. But, unlike setTimeout
, it starts the function execution not once, but regularly repeats it after a specified time interval. You can stop execution by calling clearInterval(timerId)
.
The following example will display a message every two seconds at startup until 5 seconds has passed:
1 | var timerId = setInterval( function () { |
2 | alert( "тик" ); |
3 | }, 2000); |
4 |
5 | setTimeout( function () { |
6 | clearInterval(timerId); |
7 | alert( 'стоп' ); |
8 | }, 5000); |
What happens if you do not press OK
for a long time on the alert
that appears?
It depends on the browser.
In Chrome, Opera and Safari browsers, the internal timer “freezes” during the alert/confirm/prompt
display and continues counting from the time it is closed. Therefore, after closing the alert
in any case, it will take two seconds to the next tick.
But in IE and Firefox, the internal timer will continue to go, and if you do not close the alert
long time, the next call may be appropriate. But, since the browser cannot show the new alert
while this one is open, it will wait for pressing OK
, and then it will show the new alert
right away .
setTimeout
with NFE It so happens that the function must be performed at a certain interval, but the next interval is determined on the basis of its last result.
The real example is that we are trying to connect to the server to receive data, but this does not work, for example, because the server is overloaded (who knows, maybe an attack on it).
In order not to load the server even more, we will make the next data request at a slightly longer interval, then if there is still a problem - even more, and so on up to the maximum interval, when we stop the auto-queries and suggest the user decide what to do. Something like this, for example, Gmail.
Here, so as not to be distracted by other topics,
For example, we will display an alert
with a random interval:
For example, we are writing an application that tries once a second to join the server and retrieve data from it. The connect()
function will do this.
setInterval
A call to setInterval(функция, задержка)
puts the функцию
to be executed at a specified time interval. But there is a subtlety.
In fact, the pause between calls is less than the specified interval.
For example, take setInterval(function() { func(i++) }, 100)
. It performs func
every 100 ms, increasing the counter value each time.
In the picture below, the red block is the func
execution time. The time between blocks is the time between starts of the function, and it is less than the set delay!
That is, the browser initiates the launch of the function carefully every 100мс
, without taking into account the execution time of the function itself.
It happens that the execution of a function takes more time than the delay. For example, the function is complex, and the delay is small. Or the function contains alert/confirm/prompt
statements that block the flow of execution. In this case, interesting things start.
If the launch of the function is not possible, because the browser is busy, it will be queued and executed as soon as the browser is free.
The image below illustrates what is happening for a function that takes a long time to execute.
The function call initiated by setInterval
is added to the queue and immediately occurs when this becomes possible:
The second launch of the function occurs immediately after the end of the first:
More than once in the queue execution is not set.
If the execution of the function takes more time than several scheduled executions, then it will still stand in the queue once. So there is no “accumulation” of launches.
In the image below, setInterval
tries to execute the function at 200 ms and puts the call in a queue. At 300 ms and 400 ms, the timer wakes up again, but nothing passes.
Let's look at an example of how this works.
The internal timer in Safari / Chrome browsers does not tick during alert/confirm/prompt
. If there are 3 seconds left before the execution, then even when the alert
shown for a minute - the delay remains 3 seconds.
Therefore, the example below is not reproduced in these browsers. Other browsers are fine.
alert
. While the modal window is displayed, the execution of JavaScript is blocked. Wait a bit and click OK. Стоп
button. 1 | < input type = "button" onclick = "clearInterval(timer)" value = "Стоп" > |
2 |
3 | <script> |
4 | var i = 1; |
5 | var timer = setInterval( function () { alert(i++) }, 2000); |
6 | </script> |
The following happens.
alert
window pops up - the execution is blocked and remains blocked all the time while the alert
displayed. Calling setInterval(функция, задержка)
does not guarantee a real delay between executions.
There are cases when the real delay is more or less than the specified one. In general, not the fact that there will be at least some delay.
setTimeout
In cases when not just regular repetition is necessary, but a delay between starts is required, the re-setting of setTimeout
used each time the function is executed.
Below is an example that issues an alert
at intervals of 2 seconds between them .
01 | < input type = "button" onclick = "clearTimeout(timer)" value = "Стоп" > |
02 |
03 | <script> |
04 | var i = 1; |
05 |
06 | var timer = setTimeout( function run() { |
07 | alert(i++); |
08 | timer = setTimeout(run, 2000); |
09 | }, 2000); |
10 |
11 | </script> |
On the timeline, there will be fixed delays between starts. Illustration for 100ms delay:
The browser timer has the lowest possible delay. It varies from approximately zero to 4ms in modern browsers. In older it can be more and reach 15ms.
According to the standard, the minimum delay is 4ms. So there is no difference between setTimeout(..,1)
and setTimeout(..,4)
.
See the minimum resolution "live" by the following example.
In the example below, there are DIV'ы
, each extended by a call to setInterval
with the delay specified in it - from 0ms (top) to 20ms (bottom).
Run it in various browsers, in particular, in Chrome and Firefox. You will surely notice that the first few DIV'ов
are animated at the same speed. This is precisely because the timer does not distinguish too small delays.
Open in new window Open in sandbox
The zero delay setTimeout
and setInterval
behavior has browser features.
setTimeout(.., 0)
is the same as setTimeout(.., 4)
. It is performed less frequently than setTimeout(.. ,2)
. This is a feature of this browser. setInterval(.., 0)
will not work. This concerns setInterval
, i.e. setTimeout(.., 0)
works fine. The example below implements the same animation, but via setTimeout
. If you look at it in various browsers, you can notice the differences from setInterval
.
Open in new window Open in sandbox
In some cases, the delay may not be 4ms, but 30ms or even 1000ms.
setTimeout/setInterval
, even if the tab is inactive. At the same time, a number of them (Chrome, FF, IE10) reduce the minimum frequency of the timer, to 1 time per second. It turns out that in the “background” tab the timer will work, but rarely.
setInterval
starts will be missed. Conclusion: the 4ms frequency should be oriented, but you should not count.
Let's look at reducing the frequency in action on a small example.
When you click on the button below, setInterval(..., 90)
launched, which lists the time intervals between the last 25 timer triggers. Run it. Go to another tab and return.
If your browser increases the timeout with background tab execution, you will see extended intervals marked in red.
In addition, you will definitely see that the timer is not perfectly accurate.
The code that is used in the example above and considers the time intervals between calls looks like this:
01 | var timeMark = new Date; |
02 | setTimeout( function go() { |
03 | var diff = new Date - timeMark; |
04 |
05 | // вывести очередную задержку в консоль вместо страницы |
06 | console.log(diff); |
07 |
08 | // запомним время в самом конце, |
09 | // чтобы измерить задержку именно между вызовами |
10 | timeMark = new Date; |
11 |
12 | setTimeout(go, 100); |
13 | }, 100); |
Zero or short timeouts are also used to break the execution flow of “heavy” scripts.
For example, the script for syntax highlighting should analyze the code, create many color elements for highlighting and add them to the document - on a large file it will take a lot of time.
The browser will first eat 100% of the processor, and then it may indicate that the script runs too long.
In order to avoid this, the complex task is divided into parts, the execution of each part is started at a mini-interval after the previous one, to give the browser time. For example, it is planned to highlight 20 lines every 10ms.
setTimeout(func, 0)
This trick is worthy of entering the annals of JavaScript hacks.
The function is wrapped in setTimeout(func, 0)
if they want to start it after the end of the current script.
The fact is that setTimeout
never performs a function immediately. He only plans its implementation. But the JavaScript interpreter will start performing scheduled functions only after the execution of the current script.
By standard, setTimeout
cannot perform a function with a delay of 0
anyway. As we said before, the delay is usually 4ms. But the main thing here is that the execution in any case will be after the execution of the current code.
For example:
01 | var result; |
02 |
03 | function showResult() { |
04 | alert(result); |
05 | } |
06 |
07 | setTimeout(showResult, 0); |
08 |
09 | result = 2*2; |
10 |
11 | // выведет 4 |
Later, in the chapter Managing the Processing Order, setTimeout (... 0), we will look at the various uses of this trick when dealing with events.
The setInterval(func, delay)
and setTimeout(func, delay)
methods allow you to run func
regularly / once after a delay
milliseconds.
Both methods return a timer identifier. It is used to stop a call to clearInterval/clearTimeout
.
setInterval | setTimeout | |
Timing | There is a call strictly on the timer. If the interpreter is busy, one call is queued. The execution time of the function is not taken into account, so the time from the end of one run to the beginning of another may be different. | The recursive setTimeout call is used instead of setInterval where a fixed pause between executions is needed. |
Delay | Minimum delay: 4ms. | Minimum delay: 4ms. |
The minimum delay for these methods in modern browsers is different and ranges from approximately zero to 4 ms. In older browsers, it can reach up to 15ms. | ||
Browser features | In IE, the delay 0 does not work. | In Opera, zero delay is equivalent to 4ms, the remaining delays are handled accurately, including non-standard 1ms, 2ms and 3ms. |
Comments
To leave a comment
Scripting client side JavaScript, jqvery, BackBone
Terms: Scripting client side JavaScript, jqvery, BackBone