This commit is contained in:
Ilya Kantor 2019-09-02 21:58:47 +03:00
parent 1efa9c7fe8
commit 427fbea180
4 changed files with 10 additions and 11 deletions

View file

@ -18,7 +18,7 @@ function printNumbers(from, to) {
printNumbers(5, 10); printNumbers(5, 10);
``` ```
Using recursive `setTimeout`: Using nested `setTimeout`:
```js run ```js run

View file

@ -9,5 +9,4 @@ Write a function `printNumbers(from, to)` that outputs a number every second, st
Make two variants of the solution. Make two variants of the solution.
1. Using `setInterval`. 1. Using `setInterval`.
2. Using recursive `setTimeout`. 2. Using nested `setTimeout`.

View file

@ -132,11 +132,11 @@ In most browsers, including Chrome and Firefox the internal timer continues "tic
So if you run the code above and don't dismiss the `alert` window for some time, then in the next `alert` will be shown immediately as you do it. The actual interval between alerts will be shorter than 2 seconds. So if you run the code above and don't dismiss the `alert` window for some time, then in the next `alert` will be shown immediately as you do it. The actual interval between alerts will be shorter than 2 seconds.
``` ```
## Recursive setTimeout ## Nested setTimeout
There are two ways of running something regularly. There are two ways of running something regularly.
One is `setInterval`. The other one is a recursive `setTimeout`, like this: One is `setInterval`. The other one is a nested `setTimeout`, like this:
```js ```js
/** instead of: /** instead of:
@ -153,7 +153,7 @@ let timerId = setTimeout(function tick() {
The `setTimeout` above schedules the next call right at the end of the current one `(*)`. The `setTimeout` above schedules the next call right at the end of the current one `(*)`.
The recursive `setTimeout` is a more flexible method than `setInterval`. This way the next call may be scheduled differently, depending on the results of the current one. The nested `setTimeout` is a more flexible method than `setInterval`. This way the next call may be scheduled differently, depending on the results of the current one.
For instance, we need to write a service that sends a request to the server every 5 seconds asking for data, but in case the server is overloaded, it should increase the interval to 10, 20, 40 seconds... For instance, we need to write a service that sends a request to the server every 5 seconds asking for data, but in case the server is overloaded, it should increase the interval to 10, 20, 40 seconds...
@ -177,7 +177,7 @@ let timerId = setTimeout(function request() {
And if the functions that we're scheduling are CPU-hungry, then we can measure the time taken by the execution and plan the next call sooner or later. And if the functions that we're scheduling are CPU-hungry, then we can measure the time taken by the execution and plan the next call sooner or later.
**Recursive `setTimeout` allows to set the delay between the executions more precisely than `setInterval`.** **Nested `setTimeout` allows to set the delay between the executions more precisely than `setInterval`.**
Let's compare two code fragments. The first one uses `setInterval`: Let's compare two code fragments. The first one uses `setInterval`:
@ -188,7 +188,7 @@ setInterval(function() {
}, 100); }, 100);
``` ```
The second one uses recursive `setTimeout`: The second one uses nested `setTimeout`:
```js ```js
let i = 1; let i = 1;
@ -214,11 +214,11 @@ In this case the engine waits for `func` to complete, then checks the scheduler
In the edge case, if the function always executes longer than `delay` ms, then the calls will happen without a pause at all. In the edge case, if the function always executes longer than `delay` ms, then the calls will happen without a pause at all.
And here is the picture for the recursive `setTimeout`: And here is the picture for the nested `setTimeout`:
![](settimeout-interval.svg) ![](settimeout-interval.svg)
**The recursive `setTimeout` guarantees the fixed delay (here 100ms).** **The nested `setTimeout` guarantees the fixed delay (here 100ms).**
That's because a new call is planned at the end of the previous one. That's because a new call is planned at the end of the previous one.

View file

@ -105,7 +105,7 @@ Also, `resolve`/`reject` expect only one argument (or none) and will ignore addi
```` ````
```smart header="Reject with `Error` objects" ```smart header="Reject with `Error` objects"
In case something goes wrong, we must call `reject`. That can be done with any type of argument (just like `resolve`). But it is recommended to use `Error` objects (or objects that inherit from `Error`). The reasoning for that will soon become apparent. In case something goes wrong, the executor should call `reject`. That can be done with any type of argument (just like `resolve`). But it is recommended to use `Error` objects (or objects that inherit from `Error`). The reasoning for that will soon become apparent.
``` ```
````smart header="Immediately calling `resolve`/`reject`" ````smart header="Immediately calling `resolve`/`reject`"