From 18b85c6fe84e35457a680171ec69a82f3c049637 Mon Sep 17 00:00:00 2001 From: u_m1pv8 Date: Sat, 14 Oct 2023 19:35:49 +0500 Subject: [PATCH 01/19] =?UTF-8?q?=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=B7=D0=B0=D0=B4=D0=B0=D1=87=20deb?= =?UTF-8?q?ounce,=20throttle=20=D0=B2=20=D1=81=D0=BE=D0=BE=D1=82=D0=B2?= =?UTF-8?q?=D0=B5=D1=82=D1=81=D1=82=D0=B2=D0=B8=D0=B8=20=D1=81=20en=20?= =?UTF-8?q?=D0=B2=D0=B5=D1=80=D1=81=D0=B8=D0=B5=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../03-debounce/_js.view/solution.js | 16 ++---- .../03-debounce/_js.view/test.js | 48 ++++++++++-------- .../03-debounce/debounce.svg | 1 + .../03-debounce/debounce.view/index.html | 24 +++++++++ .../03-debounce/solution.md | 27 +++------- .../03-debounce/task.md | 49 +++++++++++++++---- .../04-throttle/solution.md | 2 +- .../04-throttle/task.md | 15 +++--- 8 files changed, 111 insertions(+), 71 deletions(-) create mode 100644 1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/debounce.svg create mode 100644 1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/debounce.view/index.html diff --git a/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/_js.view/solution.js b/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/_js.view/solution.js index 065a77d1f9..3999156b7c 100644 --- a/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/_js.view/solution.js +++ b/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/_js.view/solution.js @@ -1,15 +1,7 @@ -function debounce(f, ms) { - - let isCooldown = false; - +function debounce(func, ms) { + let timeout; return function() { - if (isCooldown) return; - - f.apply(this, arguments); - - isCooldown = true; - - setTimeout(() => isCooldown = false, ms); + clearTimeout(timeout); + timeout = setTimeout(() => func.apply(this, arguments), ms); }; - } \ No newline at end of file diff --git a/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/_js.view/test.js b/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/_js.view/test.js index 774bc9a6fa..043e4d2a6e 100644 --- a/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/_js.view/test.js +++ b/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/_js.view/test.js @@ -1,41 +1,47 @@ -describe("debounce", function() { - before(function() { +describe('debounce', function () { + before(function () { this.clock = sinon.useFakeTimers(); }); - after(function() { + after(function () { this.clock.restore(); }); - it("вызывает функцию один раз в 'ms' мс", function() { - let log = ''; + it('для одного вызова - запускается через "ms" миллисекунд', function () { + const f = sinon.spy(); + const debounced = debounce(f, 1000); - function f(a) { - log += a; - } + debounced('test'); + assert(f.notCalled, 'не вызывается сразу'); + this.clock.tick(1000); + assert(f.calledOnceWith('test'), 'вызывается после 1000ms'); + }); - f = debounce(f, 1000); + it('для 3 вызовов - вызывает последний через "ms" миллисекунд', function () { + const f = sinon.spy(); + const debounced = debounce(f, 1000); - f(1); // вызвана - f(2); // проигнорирована + debounced('a'); + setTimeout(() => debounced('b'), 200); // проигнорирована (есть следующий вызов раньше чем 1000 мс) + setTimeout(() => debounced('c'), 500); // вызвана (последний вызов) + this.clock.tick(1000); - setTimeout(() => f(3), 100); // проигнорирована (слишком рано) - setTimeout(() => f(4), 1100); // вызвана (1000 мс истекли) - setTimeout(() => f(5), 1500); // проигнорирована (менее 1000 мс с последнего вызова) + assert(f.notCalled, 'не вызывается после 1000ms'); - this.clock.tick(5000); - assert.equal(log, "14"); + this.clock.tick(500); + + assert(f.calledOnceWith('c'), 'вызывается после 1500ms'); }); - it("сохраняет контекст вызова", function() { + it('сохраняет контекст вызова', function () { let obj = { f() { assert.equal(this, obj); - } + }, }; obj.f = debounce(obj.f, 1000); - obj.f("test"); + obj.f('test'); + this.clock.tick(5000); }); - -}); +}); \ No newline at end of file diff --git a/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/debounce.svg b/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/debounce.svg new file mode 100644 index 0000000000..e624ce0203 --- /dev/null +++ b/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/debounce.svg @@ -0,0 +1 @@ +200ms1500ms1000ms0cf(a)f(b)f(c)500mstimecalls: after 1000ms \ No newline at end of file diff --git a/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/debounce.view/index.html b/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/debounce.view/index.html new file mode 100644 index 0000000000..aab1a471bb --- /dev/null +++ b/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/debounce.view/index.html @@ -0,0 +1,24 @@ + + + +Функция handler вызывается на этом поле для ввода: +
+ + +

+ +А на этом поле функция handler вызывается с применением debounce – debounce(handler, 1000): +
+ + +

+ + + \ No newline at end of file diff --git a/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/solution.md b/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/solution.md index 82c2ecb5fe..5952020f11 100644 --- a/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/solution.md +++ b/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/solution.md @@ -1,27 +1,12 @@ ```js demo -function debounce(f, ms) { - - let isCooldown = false; - +function debounce(func, ms) { + let timeout; return function() { - if (isCooldown) return; - - f.apply(this, arguments); - - isCooldown = true; - - setTimeout(() => isCooldown = false, ms); + clearTimeout(timeout); + timeout = setTimeout(() => func.apply(this, arguments), ms); }; - } -``` - -Вызов `debounce` возвращает обёртку. Возможны два состояния: -- `isCooldown = false` -- готова к выполнению. -- `isCooldown = true` -- ожидание окончания тайм-аута. -В первом вызове `isCoolDown = false`, поэтому вызов продолжается, и состояние изменяется на `true`. - -Пока `isCoolDown` имеет значение `true`, все остальные вызовы игнорируются. +``` -Затем `setTimeout` устанавливает его в `false` после заданной задержки. +Вызов `debounce` возвращает обёртку. При вызове он планирует вызов исходной функции через указанное количество `ms` и отменяет предыдущий такой тайм-аут. \ No newline at end of file diff --git a/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/task.md b/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/task.md index 9c87aa129f..8a0bc8c6cf 100644 --- a/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/task.md +++ b/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/task.md @@ -4,20 +4,49 @@ importance: 5 # Декоратор debounce -Результатом декоратора `debounce(f, ms)` должна быть обёртка, которая передаёт вызов `f` не более одного раза в `ms` миллисекунд. -Другими словами, когда мы вызываем `debounce`, это гарантирует, что все остальные вызовы будут игнорироваться в течение `ms`. +Результат `debounce(f, ms)` декоратора – это обёртка, которая откладывает вызовы `f`, пока не пройдёт `ms` миллисекунд бездействия (без вызовов, “cooldown period”), а затем вызывает `f` один раз с последними аргументами. -Например: +Другими словами, `debounce` – это такой секретарь, который принимает “телефонные звонки”, и ждёт, пока не пройдет `ms` миллисекунд тишины. И только потом передает “начальнику” информацию о последнем звонке (вызывает фактическую `f`). + +Например, у нас была функция `f`, и мы заменили её на `f = debounce(f, 1000)`. + +Затем, если обёрнутая функция вызывается в 0, 200 и 500 мс, а потом вызовов нет, то фактическая `f` будет вызвана только один раз, в 1500 мс. То есть: по истечению 1000 мс от последнего вызова. + +![](debounce.svg) + +...И она получит аргументы самого последнего вызова, остальные вызовы игнорируются. + +Ниже код этого примера (используется декоратор debounce из библиотеки [Lodash library](https://lodash.com/docs/4.17.15#debounce)): ```js no-beautify -let f = debounce(alert, 1000); +let f = _.debounce(alert, 1000); + +f("a"); +setTimeout( () => f("b"), 200); +setTimeout( () => f("c"), 500); + +// Обёрнутая в debounce функция ждёт 1000 мс после последнего вызова, а затем запускает: alert("c") +``` -f(1); // выполняется немедленно -f(2); // проигнорирован +Теперь практический пример. Представим что пользователь набирает какой-то текст, и мы хотим отправить запрос на сервер, когда ввод текста будет завершён. -setTimeout( () => f(3), 100); // проигнорирован (прошло только 100 мс) -setTimeout( () => f(4), 1100); // выполняется -setTimeout( () => f(5), 1500); // проигнорирован (прошло только 400 мс от последнего вызова) +Нет смысла отправлять запрос для каждого набранного символа. Вместо этого мы хотели бы подождать, а затем обработать весь результат. + +В браузере мы можем настроить обработчик событий – функцию, которая вызывается при каждом изменении поля для ввода. Обычно обработчик событий вызывается очень часто, для каждого набранного символа. Но если мы воспользуемся `debounce` на 1000 мс, то он будет вызван только один раз, через 1000 мс после последнего ввода символа. + +```online + +В этом живом примере обработчик помещает результат в поле ниже, попробуйте: + +[iframe border=1 src="debounce" height=200] + +Видите? На втором поле вызывается функция, обёрнутая в `debounce`, поэтому его содержимое обрабатывается через 1000 мс с момента последнего ввода. ``` -На практике `debounce` полезен для функций, которые получают/обновляют данные, и мы знаем, что повторный вызов в течение короткого промежутка времени не даст ничего нового. Так что лучше не тратить на него ресурсы. +Таким образом `debounce` – это отличный способ обработать последовательность событий: будь то последовательность нажатий клавиш, движений мыши или ещё что-либо. + +Он ждёт заданное время после последнего вызова, а затем запускает свою функцию, которая может обработать результат. + +Задача — реализовать декоратор `debounce`. + +Подсказка: это всего лишь несколько строк, если вы задумались об этом :) \ No newline at end of file diff --git a/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/solution.md b/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/solution.md index 4d64b9d427..1f1a8c24c1 100644 --- a/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/solution.md +++ b/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/solution.md @@ -34,6 +34,6 @@ function throttle(func, ms) { 1. Во время первого вызова обёртка просто вызывает `func` и устанавливает состояние задержки (`isThrottled = true`). 2. В этом состоянии все вызовы запоминаются в `saveArgs / saveThis`. Обратите внимание, что контекст и аргументы одинаково важны и должны быть запомнены. Они нам нужны для того, чтобы воспроизвести вызов позднее. -3. ... Затем по прошествии `ms` миллисекунд срабатывает `setTimeout`. Состояние задержки сбрасывается (`isThrottled = false`). И если мы проигнорировали вызовы, то "обёртка" выполняется с последними запомненными аргументами и контекстом. +3. Затем по прошествии `ms` миллисекунд срабатывает `setTimeout`. Состояние задержки сбрасывается (`isThrottled = false`). И если мы проигнорировали вызовы, то "обёртка" выполняется с последними запомненными аргументами и контекстом. На третьем шаге выполняется не `func`, а `wrapper`, потому что нам нужно не только выполнить `func`, но и ещё раз установить состояние задержки и таймаут для его сброса. diff --git a/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/task.md b/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/task.md index fe5949e7df..00e709d2ed 100644 --- a/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/task.md +++ b/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/task.md @@ -4,18 +4,21 @@ importance: 5 # Тормозящий (throttling) декоратор -Создайте "тормозящий" декоратор `throttle(f, ms)`, который возвращает обёртку, передавая вызов в `f` не более одного раза в `ms` миллисекунд. Те вызовы, которые попадают в период "торможения", игнорируются. +Создайте "тормозящий" декоратор `throttle(f, ms)` – который возвращает обёртку. -**Отличие от `debounce` - если проигнорированный вызов является последним во время "задержки", то он выполняется в конце.** +Когда он вызывается несколько раз, он передает вызов `f` максимум один раз в `ms` миллисекунд. -Давайте рассмотрим реальное применение, чтобы лучше понять это требование и выяснить, откуда оно взято. +По сравнению с декоратором debounce поведение совершенно другое: +- `debounce` запускает функцию один раз после периода “бездействия”. Подходит для обработки конечного результата. +- `throttle` запускает функцию не чаще, чем указанное время `ms`. Подходит для регулярных обновлений, которые не должны быть слишком частыми. -**Например, мы хотим отслеживать движения мыши.** +Другими словами, `throttle` похож на секретаря, который принимает телефонные звонки, но беспокоит начальника (вызывает фактическую `f`) не чаще, чем раз в `ms` миллисекунд. +Давайте рассмотрим реальное применение, чтобы лучше понять это требование и выяснить, откуда оно взято. -В браузере мы можем объявить функцию, которая будет запускаться при каждом движении указателя и получать его местоположение. Во время активного использования мыши эта функция запускается очень часто, это может происходить около 100 раз в секунду (каждые 10 мс). +**Например, мы хотим отслеживать движения мыши.** -**Мы бы хотели обновлять информацию на странице при передвижениях.** +В браузере мы можем объявить функцию, которая будет запускаться при каждом движении указателя и получать его местоположение. Во время активного использования мыши эта функция запускается очень часто, это может происходить около 100 раз в секунду (каждые 10 мс). **Мы бы хотели обновлять информацию на странице при передвижениях.** ...Но функция обновления `update()` слишком ресурсоёмкая, чтобы делать это при каждом микродвижении. Да и нет смысла делать обновление чаще, чем один раз в 1000 мс. From 8e70df106a59451b7a3b57a9fabc1dc8c79b47ab Mon Sep 17 00:00:00 2001 From: Aleksandras Date: Fri, 20 Oct 2023 21:54:58 +0300 Subject: [PATCH 02/19] Update 1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/task.md --- .../09-call-apply-decorators/04-throttle/task.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/task.md b/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/task.md index 00e709d2ed..7374ff58a1 100644 --- a/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/task.md +++ b/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/task.md @@ -4,7 +4,7 @@ importance: 5 # Тормозящий (throttling) декоратор -Создайте "тормозящий" декоратор `throttle(f, ms)` – который возвращает обёртку. +Создайте «тормозящий» декоратор `throttle(f, ms)`, который возвращает обёртку. Когда он вызывается несколько раз, он передает вызов `f` максимум один раз в `ms` миллисекунд. From eee220dae32f5828737a5f6d3b23e2163092b959 Mon Sep 17 00:00:00 2001 From: Aleksandras Date: Fri, 20 Oct 2023 21:55:11 +0300 Subject: [PATCH 03/19] Update 1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/task.md --- .../09-call-apply-decorators/04-throttle/task.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/task.md b/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/task.md index 7374ff58a1..3fa9ff46f3 100644 --- a/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/task.md +++ b/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/task.md @@ -6,7 +6,7 @@ importance: 5 Создайте «тормозящий» декоратор `throttle(f, ms)`, который возвращает обёртку. -Когда он вызывается несколько раз, он передает вызов `f` максимум один раз в `ms` миллисекунд. +При многократном вызове он передает вызов `f` не чаще одного раза в `ms` миллисекунд. По сравнению с декоратором debounce поведение совершенно другое: - `debounce` запускает функцию один раз после периода “бездействия”. Подходит для обработки конечного результата. From 1371f52d51c70b4088eb8a6bf4e7cb512e857d82 Mon Sep 17 00:00:00 2001 From: Aleksandras Date: Fri, 20 Oct 2023 21:55:18 +0300 Subject: [PATCH 04/19] Update 1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/task.md --- .../09-call-apply-decorators/04-throttle/task.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/task.md b/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/task.md index 3fa9ff46f3..6618731cc7 100644 --- a/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/task.md +++ b/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/task.md @@ -8,7 +8,7 @@ importance: 5 При многократном вызове он передает вызов `f` не чаще одного раза в `ms` миллисекунд. -По сравнению с декоратором debounce поведение совершенно другое: +По сравнению с декоратором `debounce` поведение совершенно другое: - `debounce` запускает функцию один раз после периода “бездействия”. Подходит для обработки конечного результата. - `throttle` запускает функцию не чаще, чем указанное время `ms`. Подходит для регулярных обновлений, которые не должны быть слишком частыми. From e6c9bff146c80b2ac11e7b55d1092e21782977e6 Mon Sep 17 00:00:00 2001 From: Aleksandras Date: Fri, 20 Oct 2023 21:55:25 +0300 Subject: [PATCH 05/19] Update 1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/task.md --- .../09-call-apply-decorators/04-throttle/task.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/task.md b/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/task.md index 6618731cc7..0bf879f585 100644 --- a/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/task.md +++ b/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/task.md @@ -9,7 +9,7 @@ importance: 5 При многократном вызове он передает вызов `f` не чаще одного раза в `ms` миллисекунд. По сравнению с декоратором `debounce` поведение совершенно другое: -- `debounce` запускает функцию один раз после периода “бездействия”. Подходит для обработки конечного результата. +- `debounce` запускает функцию один раз после периода «бездействия». Подходит для обработки конечного результата. - `throttle` запускает функцию не чаще, чем указанное время `ms`. Подходит для регулярных обновлений, которые не должны быть слишком частыми. Другими словами, `throttle` похож на секретаря, который принимает телефонные звонки, но беспокоит начальника (вызывает фактическую `f`) не чаще, чем раз в `ms` миллисекунд. From 8f5a13fc3dd6a829f3b85f25bd25a757d30f3373 Mon Sep 17 00:00:00 2001 From: Aleksandras Date: Fri, 20 Oct 2023 21:55:34 +0300 Subject: [PATCH 06/19] Update 1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/task.md --- .../09-call-apply-decorators/04-throttle/task.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/task.md b/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/task.md index 0bf879f585..c6711943d8 100644 --- a/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/task.md +++ b/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/task.md @@ -12,7 +12,7 @@ importance: 5 - `debounce` запускает функцию один раз после периода «бездействия». Подходит для обработки конечного результата. - `throttle` запускает функцию не чаще, чем указанное время `ms`. Подходит для регулярных обновлений, которые не должны быть слишком частыми. -Другими словами, `throttle` похож на секретаря, который принимает телефонные звонки, но беспокоит начальника (вызывает фактическую `f`) не чаще, чем раз в `ms` миллисекунд. +Другими словами, `throttle` похож на секретаря, который принимает телефонные звонки, но при этом беспокоит начальника (вызывает непосредственно `f`) не чаще, чем один раз в `ms` миллисекунд. Давайте рассмотрим реальное применение, чтобы лучше понять это требование и выяснить, откуда оно взято. From 99d405d632a36ac7e432c4bf43eeaadc919f0e30 Mon Sep 17 00:00:00 2001 From: Aleksandras Date: Fri, 20 Oct 2023 21:55:40 +0300 Subject: [PATCH 07/19] Update 1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/task.md --- .../09-call-apply-decorators/03-debounce/task.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/task.md b/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/task.md index 8a0bc8c6cf..2f3f0ef73c 100644 --- a/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/task.md +++ b/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/task.md @@ -40,7 +40,7 @@ setTimeout( () => f("c"), 500); [iframe border=1 src="debounce" height=200] -Видите? На втором поле вызывается функция, обёрнутая в `debounce`, поэтому его содержимое обрабатывается через 1000 мс с момента последнего ввода. +Видите? На втором поле вызывается функция, обёрнутая в `debounce`, поэтому его содержимое обрабатывается через 1000мс с момента последнего ввода. ``` Таким образом `debounce` – это отличный способ обработать последовательность событий: будь то последовательность нажатий клавиш, движений мыши или ещё что-либо. From b7db5ac9b2213eb35931be23c30bd8d09da04cd3 Mon Sep 17 00:00:00 2001 From: Aleksandras Date: Fri, 20 Oct 2023 21:55:55 +0300 Subject: [PATCH 08/19] Update 1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/task.md --- .../09-call-apply-decorators/03-debounce/task.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/task.md b/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/task.md index 2f3f0ef73c..6182d6f082 100644 --- a/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/task.md +++ b/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/task.md @@ -43,7 +43,7 @@ setTimeout( () => f("c"), 500); Видите? На втором поле вызывается функция, обёрнутая в `debounce`, поэтому его содержимое обрабатывается через 1000мс с момента последнего ввода. ``` -Таким образом `debounce` – это отличный способ обработать последовательность событий: будь то последовательность нажатий клавиш, движений мыши или ещё что-либо. +Таким образом, `debounce` – это отличный способ обработать последовательность событий: будь то последовательность нажатий клавиш, движений мыши или ещё что-либо. Он ждёт заданное время после последнего вызова, а затем запускает свою функцию, которая может обработать результат. From b758d8d108949647369a5a4db981622a62d22d53 Mon Sep 17 00:00:00 2001 From: Aleksandras Date: Fri, 20 Oct 2023 21:56:02 +0300 Subject: [PATCH 09/19] Update 1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/task.md --- .../09-call-apply-decorators/03-debounce/task.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/task.md b/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/task.md index 6182d6f082..3f358556a5 100644 --- a/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/task.md +++ b/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/task.md @@ -49,4 +49,4 @@ setTimeout( () => f("c"), 500); Задача — реализовать декоратор `debounce`. -Подсказка: это всего лишь несколько строк, если вы задумались об этом :) \ No newline at end of file +Подсказка: это всего лишь несколько строк, если вдуматься :) \ No newline at end of file From bd344f14792e600737ccfa7b35dc963446b7cfe4 Mon Sep 17 00:00:00 2001 From: Aleksandras Date: Fri, 20 Oct 2023 21:56:09 +0300 Subject: [PATCH 10/19] Update 1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/_js.view/test.js --- .../09-call-apply-decorators/03-debounce/_js.view/test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/_js.view/test.js b/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/_js.view/test.js index 043e4d2a6e..ed5e2f3020 100644 --- a/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/_js.view/test.js +++ b/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/_js.view/test.js @@ -22,7 +22,7 @@ describe('debounce', function () { const debounced = debounce(f, 1000); debounced('a'); - setTimeout(() => debounced('b'), 200); // проигнорирована (есть следующий вызов раньше чем 1000 мс) + setTimeout(() => debounced('b'), 200); // проигнорирована setTimeout(() => debounced('c'), 500); // вызвана (последний вызов) this.clock.tick(1000); From 315e971f2e91b6acb5f9686500b3b77de991b231 Mon Sep 17 00:00:00 2001 From: Aleksandras Date: Fri, 20 Oct 2023 21:56:15 +0300 Subject: [PATCH 11/19] Update 1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/_js.view/test.js --- .../09-call-apply-decorators/03-debounce/_js.view/test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/_js.view/test.js b/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/_js.view/test.js index ed5e2f3020..bceaefee24 100644 --- a/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/_js.view/test.js +++ b/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/_js.view/test.js @@ -23,7 +23,7 @@ describe('debounce', function () { debounced('a'); setTimeout(() => debounced('b'), 200); // проигнорирована - setTimeout(() => debounced('c'), 500); // вызвана (последний вызов) + setTimeout(() => debounced('c'), 500); // вызвана this.clock.tick(1000); assert(f.notCalled, 'не вызывается после 1000ms'); From 77502a109699f0dbbe95a6b5c1a37966a88d2c30 Mon Sep 17 00:00:00 2001 From: Aleksandras Date: Fri, 20 Oct 2023 21:56:35 +0300 Subject: [PATCH 12/19] Update 1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/task.md --- .../09-call-apply-decorators/04-throttle/task.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/task.md b/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/task.md index c6711943d8..f6f7aab282 100644 --- a/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/task.md +++ b/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/task.md @@ -18,7 +18,7 @@ importance: 5 **Например, мы хотим отслеживать движения мыши.** -В браузере мы можем объявить функцию, которая будет запускаться при каждом движении указателя и получать его местоположение. Во время активного использования мыши эта функция запускается очень часто, это может происходить около 100 раз в секунду (каждые 10 мс). **Мы бы хотели обновлять информацию на странице при передвижениях.** +В браузере мы можем реализовать функцию, которая будет запускаться при каждом перемещении указателя и получать его местоположение. Во время активного использования мыши эта функция запускается очень часто, что-то около 100 раз в секунду (каждые 10 мс). **Мы бы хотели обновлять некоторую информацию на странице при передвижении указателя.** ...Но функция обновления `update()` слишком ресурсоёмкая, чтобы делать это при каждом микродвижении. Да и нет смысла делать обновление чаще, чем один раз в 1000 мс. From 7a7ef75e3c531c6e5dc8a5b26ae85902d647087d Mon Sep 17 00:00:00 2001 From: Aleksandras Date: Fri, 20 Oct 2023 21:56:48 +0300 Subject: [PATCH 13/19] Update 1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/task.md --- .../09-call-apply-decorators/03-debounce/task.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/task.md b/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/task.md index 3f358556a5..2e1084fa1f 100644 --- a/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/task.md +++ b/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/task.md @@ -4,7 +4,7 @@ importance: 5 # Декоратор debounce -Результат `debounce(f, ms)` декоратора – это обёртка, которая откладывает вызовы `f`, пока не пройдёт `ms` миллисекунд бездействия (без вызовов, “cooldown period”), а затем вызывает `f` один раз с последними аргументами. +Результат декоратора `debounce(f, ms)` – это обёртка, которая откладывает вызовы `f`, пока не пройдёт `ms` миллисекунд бездействия (без вызовов, «cooldown period»), а затем вызывает `f` один раз с последними аргументами. Другими словами, `debounce` – это такой секретарь, который принимает “телефонные звонки”, и ждёт, пока не пройдет `ms` миллисекунд тишины. И только потом передает “начальнику” информацию о последнем звонке (вызывает фактическую `f`). From 3076e768810709ee5969319d208d653b7ef9891c Mon Sep 17 00:00:00 2001 From: Aleksandras Date: Fri, 20 Oct 2023 21:57:03 +0300 Subject: [PATCH 14/19] Update 1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/task.md --- .../09-call-apply-decorators/03-debounce/task.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/task.md b/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/task.md index 2e1084fa1f..5017aa3c4a 100644 --- a/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/task.md +++ b/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/task.md @@ -6,7 +6,7 @@ importance: 5 Результат декоратора `debounce(f, ms)` – это обёртка, которая откладывает вызовы `f`, пока не пройдёт `ms` миллисекунд бездействия (без вызовов, «cooldown period»), а затем вызывает `f` один раз с последними аргументами. -Другими словами, `debounce` – это такой секретарь, который принимает “телефонные звонки”, и ждёт, пока не пройдет `ms` миллисекунд тишины. И только потом передает “начальнику” информацию о последнем звонке (вызывает фактическую `f`). +Другими словами, `debounce` – это так называемый секретарь, который принимает «телефонные звонки», и ждёт, пока не пройдет `ms` миллисекунд тишины. И только после этого передает «начальнику» информацию о последнем звонке (вызывает непосредственно `f`). Например, у нас была функция `f`, и мы заменили её на `f = debounce(f, 1000)`. From 432646fae306d9f471b0534b6b3f38fb64d0dede Mon Sep 17 00:00:00 2001 From: Aleksandras Date: Fri, 20 Oct 2023 21:57:12 +0300 Subject: [PATCH 15/19] Update 1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/task.md --- .../09-call-apply-decorators/03-debounce/task.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/task.md b/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/task.md index 5017aa3c4a..86ff11709d 100644 --- a/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/task.md +++ b/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/task.md @@ -8,7 +8,7 @@ importance: 5 Другими словами, `debounce` – это так называемый секретарь, который принимает «телефонные звонки», и ждёт, пока не пройдет `ms` миллисекунд тишины. И только после этого передает «начальнику» информацию о последнем звонке (вызывает непосредственно `f`). -Например, у нас была функция `f`, и мы заменили её на `f = debounce(f, 1000)`. +Например, у нас была функция `f` и мы заменили её на `f = debounce(f, 1000)`. Затем, если обёрнутая функция вызывается в 0, 200 и 500 мс, а потом вызовов нет, то фактическая `f` будет вызвана только один раз, в 1500 мс. То есть: по истечению 1000 мс от последнего вызова. From 2403bac120beb5081dd99c616812cfe74c6a6cda Mon Sep 17 00:00:00 2001 From: Aleksandras Date: Fri, 20 Oct 2023 21:57:25 +0300 Subject: [PATCH 16/19] Update 1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/debounce.svg --- .../09-call-apply-decorators/03-debounce/debounce.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/debounce.svg b/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/debounce.svg index e624ce0203..8e128ce74d 100644 --- a/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/debounce.svg +++ b/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/debounce.svg @@ -1 +1 @@ -200ms1500ms1000ms0cf(a)f(b)f(c)500mstimecalls: after 1000ms \ No newline at end of file +200мс1500мс1000мс0cf(a)f(b)f(c)500мсвремявызовы: после 1000мс \ No newline at end of file From 4e49905fafdedcc296c3265c2a588aa9436d41cf Mon Sep 17 00:00:00 2001 From: Aleksandras Date: Fri, 20 Oct 2023 21:57:34 +0300 Subject: [PATCH 17/19] Update 1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/task.md --- .../09-call-apply-decorators/03-debounce/task.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/task.md b/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/task.md index 86ff11709d..9993bffb42 100644 --- a/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/task.md +++ b/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/task.md @@ -16,7 +16,7 @@ importance: 5 ...И она получит аргументы самого последнего вызова, остальные вызовы игнорируются. -Ниже код этого примера (используется декоратор debounce из библиотеки [Lodash library](https://lodash.com/docs/4.17.15#debounce)): +Ниже код этого примера (используется декоратор debounce из библиотеки [Lodash](https://lodash.com/docs/4.17.15#debounce)): ```js no-beautify let f = _.debounce(alert, 1000); From 777819ccd7469cc76e3d9c3d2d6ee8c7c30af37f Mon Sep 17 00:00:00 2001 From: Aleksandras Date: Fri, 20 Oct 2023 21:57:45 +0300 Subject: [PATCH 18/19] Update 1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/task.md --- .../09-call-apply-decorators/03-debounce/task.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/task.md b/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/task.md index 9993bffb42..cb04481db3 100644 --- a/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/task.md +++ b/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/task.md @@ -32,7 +32,7 @@ setTimeout( () => f("c"), 500); Нет смысла отправлять запрос для каждого набранного символа. Вместо этого мы хотели бы подождать, а затем обработать весь результат. -В браузере мы можем настроить обработчик событий – функцию, которая вызывается при каждом изменении поля для ввода. Обычно обработчик событий вызывается очень часто, для каждого набранного символа. Но если мы воспользуемся `debounce` на 1000 мс, то он будет вызван только один раз, через 1000 мс после последнего ввода символа. +В браузере мы можем настроить обработчик событий – функцию, которая вызывается при каждом изменении поля для ввода. Обычно обработчик событий вызывается очень часто, для каждого набранного символа. Но если мы воспользуемся `debounce` на 1000мс, то он будет вызван только один раз, через 1000мс после последнего ввода символа. ```online From ccf8ef46d2dfd676c78149a43bb56a10cda1f6a8 Mon Sep 17 00:00:00 2001 From: Aleksandras Date: Fri, 20 Oct 2023 21:57:54 +0300 Subject: [PATCH 19/19] Update 1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/task.md --- .../09-call-apply-decorators/03-debounce/task.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/task.md b/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/task.md index cb04481db3..bea131145e 100644 --- a/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/task.md +++ b/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/task.md @@ -28,7 +28,7 @@ setTimeout( () => f("c"), 500); // Обёрнутая в debounce функция ждёт 1000 мс после последнего вызова, а затем запускает: alert("c") ``` -Теперь практический пример. Представим что пользователь набирает какой-то текст, и мы хотим отправить запрос на сервер, когда ввод текста будет завершён. +Теперь практический пример. Предположим, пользователь набирает какой-то текст, и мы хотим отправить запрос на сервер, когда ввод этого текста будет завершён. Нет смысла отправлять запрос для каждого набранного символа. Вместо этого мы хотели бы подождать, а затем обработать весь результат.