You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Это не работает, потому что `setTimeout` ожидает ссылку на функцию. Здесь `sayHi()` запускает выполнение функции и *результат выполнения* отправляется в `setTimeout`. В нашем случае результатом выполнения `sayHi()` является `undefined` (так как функция ничего не возвращает), поэтому и нечего планировать.
78
+
Это не работает, потому что `setTimeout` ожидает ссылку на функцию. Здесь `sayHi()` запускает выполнение функции и *результат выполнения* отправляется в `setTimeout`. В нашем случае результатом выполнения `sayHi()` является `undefined` (так как функция ничего не возвращает), поэтому ничего не планируется.
79
79
````
80
80
81
81
### Отмена через clearTimeout
@@ -99,7 +99,7 @@ clearTimeout(timerId);
99
99
alert(timerId); // тот же идентификатор (не принимает значение null после отмены)
100
100
```
101
101
102
-
Как мы видим, в результате вывода `alert` в браузере идентификатором таймера является число. В других средах это может быть что-то еще. Например, Node.js возвращает объект таймера с дополнительными методами.
102
+
Как мы видим из вывода `alert`, в браузере идентификатором таймера является число. В других средах это может быть что-то еще. Например, Node.js возвращает объект таймера с дополнительными методами.
103
103
104
104
Повторюсь, что нет единой спецификации на эти методы, поэтому такое поведение является нормальным.
Все аргументы имеют такое же значение. Но отличие этого метода от `setTimeout` в том, что функция запускается не один раз, а периодически через указанный интервал времени.
117
117
118
-
Чтобы остановить дальнейшее выполнение функции необходимо вызвать `clearInterval(timerId)`.
118
+
Чтобы остановить дальнейшее выполнение функции, необходимо вызвать `clearInterval(timerId)`.
119
119
120
120
Следующий пример выводит сообщение каждые 2 секунды. Через 5 секунд вывод прекращается:
121
121
@@ -154,7 +154,7 @@ let timerId = setTimeout(function tick() {
154
154
155
155
Метод `setTimeout` выше планирует следующий вызов прямо после окончания текущего `(*)`.
156
156
157
-
Рекурсивный `setTimeout` более гибкий метод, чем `setInterval`. Таким образом, следующий вызов может быть задан по-разному, в зависимости от результатов текущего.
157
+
Рекурсивный `setTimeout`- более гибкий метод, чем `setInterval`. С его помощью, последующий вызов может быть задан по-разному, в зависимости от результатов предыдущего.
158
158
159
159
Например, необходимо написать сервис, который отправляет запрос для получения данных на сервер каждые 5 секунд, но если сервер перегружен, то необходимо увеличить интервал запросов до 10, 20, 40 секунд...
160
160
Вот псевдокод:
@@ -175,9 +175,9 @@ let timerId = setTimeout(function request() {
175
175
```
176
176
177
177
178
-
И если мы постоянно получаем ресурсоемкие задачи, то можем измерить время, затраченное на выполнение, и спланировать следующий вызов раньше или позже.
178
+
А если функции, которые мы планируем, ресурсоёмкие и требуют времени, то можем измерить время, затраченное на выполнение, и спланировать следующий вызов раньше или позже.
179
179
180
-
**Рекурсивный `setTimeout` гарантирует задержку между извлечениями, `setInterval` -- нет.**
180
+
**Рекурсивный `setTimeout` гарантирует задержку между выполнениями, `setInterval` -- нет.**
181
181
182
182
Сравним два фрагмента кода. Первый использует `setInterval`:
Для `setInterval` функция остается в памяти до тех, пока не будет вызван `clearInterval`.
234
234
235
-
Это побочный эффект. Функция ссылается на внешнее лексическое окружение, поэтому пока она существует, внешние переменные существуют тоже. Они могут занимать больше памяти, чем сама функция. Поэтому если нет больше необходимости планирования вызова функции, то лучше отменить его, даже если он не очень большой.
235
+
Есть и побочный эффект. Функция ссылается на внешнее лексическое окружение, поэтому пока она существует, внешние переменные существуют тоже. Они могут занимать больше памяти, чем сама функция. Поэтому, если нет регулярный вызов функции больше не нужен, то лучше отменить его, даже если функция очень маленькая.
236
236
````
237
237
238
238
## setTimeout(...,0)
239
239
240
240
Особый вариант использования: `setTimeout(func, 0)` или просто `setTimeout(func)`.
241
241
242
-
Это планирование вызова`func` настолько быстро, насколько это возможно. Но планировщик будет вызывать функцию только после завершения выполнения текущего кода.
242
+
Это планирует вызов`func` настолько быстро, насколько это возможно. Но планировщик будет вызывать функцию только после завершения выполнения текущего кода.
243
243
244
244
Так вызов функции будет запланирован сразу после выполнения текущего кода. Другими словами, *асинхронно*.
Теперь когда запускаем `count()`и узнаем, что нам будет нужен ещё `count()`, мы планируем это сразу перед выполнением задачи.
356
+
Теперь когда в процессе рабоыт `count()`мы видим, что нам будет нужен ещё вызов`count()`, мы планируем это сразу перед выполнением задачи.
357
357
358
358
Если запустите этот код, то легко заметите, что он занимает существенно меньше времени.
359
359
@@ -379,14 +379,16 @@ setTimeout(function run() {
379
379
380
380
Первый таймер запускается сразу (как и указано в спецификации) и затем задержка вступает в игру и мы видим `9, 15, 20, 24...`.
381
381
382
-
Это ограничение существует давно и многие скрипты полагаются на него, поэтому оно существует по историческим причинам.
382
+
Это ограничение существует давно, многие скрипты полагаются на него, поэтому оно сохраняется по историческим причинам.
383
383
384
-
Этого ограничения в серверном JavaScript не существует и там есть другие способы планирования немедленной асинхронной работы. Например, [process.nextTick](https://nodejs.org/api/process.html) и [setImmediate](https://nodejs.org/api/timers.html) для Node.js. Так что это ограничение относится только к браузерам.
384
+
Этого ограничения нет в серверном JavaScript. Там есть и другие способы планирования асинхронных задач. Например, [process.nextTick](https://nodejs.org/api/process.html) и [setImmediate](https://nodejs.org/api/timers.html) для Node.js. Так что это ограничение относится только к браузерам.
385
385
````
386
386
387
387
### Даем возможность отрисовки браузеру
388
388
389
-
Другим преимуществом для браузерных скриптов является возможность показа процесса загрузки или чего-либо ещё пользователю. Это связано с тем, что браузер обычно выполняет все «перерисовки» после завершения скрипта.
389
+
Другим преимуществом разбития тяжёлых задач на части является возможность показать процесс выполнения в браузере.
390
+
391
+
Обычно браузер отрисовывает изменения после завершения выполнения текущего кода. Так что если функция меняет много элементов -- всё это мы увидим, когда текущий код будет завершён.
390
392
391
393
Поэтому, если мы делаем одну огромную функцию, то даже если она что-то меняет, изменения не отразятся в документе до ее завершения.
392
394
@@ -401,7 +403,7 @@ setTimeout(function run() {
401
403
for (let j =0; j <1e6; j++) {
402
404
i++;
403
405
// вставляем текущее значение i в <div>
404
-
// (об innerHTML поговорим в отдельной главе, но его смысл должен быть понятен)
406
+
// (об innerHTML поговорим в соответствующей главе, здесь мы просто вставляем номер в элемент)
405
407
progress.innerHTML= i;
406
408
}
407
409
}
@@ -438,20 +440,20 @@ setTimeout(function run() {
438
440
</script>
439
441
```
440
442
441
-
Теперь в `<div>`показано изменение`i`.
443
+
Теперь `<div>`показывает увеличивающиеся значения`i`.
442
444
443
445
## Итого
444
446
445
447
- Методы `setInterval(func, delay, ...args)` и `setTimeout(func, delay, ...args)` позволяют выполнять `func` регулярно или только один раз после задержки `delay`, заданной в мс.
446
448
- Для отмены выполнения необходимо вызвать `clearInterval/clearTimeout` со значением, которое возвращают методы `setInterval/setTimeout`.
447
449
- Вложенный вызов `setTimeout` является более гибкой альтернативой `setInterval`. Также он может гарантировать минимальное время *между* выполнениями.
448
-
- Планирование с нулевой задержкой `setTimeout(...,0)` используется для вызовов, которые должны быть исполнены "как можно скорее, после завершения исполнения текущего кода".
450
+
- Планирование с нулевой задержкой `setTimeout(func,0)` или, что тоже самое, `setTimeout(func)`, используется для вызовов, которые должны быть исполнены "как можно скорее, после завершения исполнения текущего кода".
449
451
450
452
Некоторые случаи использования `setTimeout(...,0)`:
451
453
- разделить ресурсоемкие задачи на части, чтобы скрипт не "зависал",
452
-
- позволить браузеру сделать что-то еще, пока идет процесс (отрисовка статуса загрузки).
454
+
- позволить браузеру сделать что-то еще, пока идет процесс (рисовать полоску прогресса).
453
455
454
-
Обратите внимание, что все методы планирования не дают *гарантию* точности задержки. Поэтому не стоит полагаться на это в запланированном коде.
456
+
Обратим внимание, что все методы планирования *не гарантируют* точную задержку. Не стоит полагаться на это в коде.
455
457
456
458
Например, таймер в браузере может замедляться по многим причинам:
0 commit comments