Skip to content

Commit c9a1058

Browse files
committed
04-throttle
1 parent f27f648 commit c9a1058

4 files changed

Lines changed: 51 additions & 51 deletions

File tree

1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/_js.view/solution.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,28 +7,28 @@ function throttle(func, ms) {
77
function wrapper() {
88

99
if (isThrottled) {
10-
// memo last arguments to call after the cooldown
10+
// запоминаем последние аргументы для вызова после задержки
1111
savedArgs = arguments;
1212
savedThis = this;
1313
return;
1414
}
1515

16-
// otherwise go to cooldown state
16+
// в противном случае переходим в состояние задержки
1717
func.apply(this, arguments);
1818

1919
isThrottled = true;
2020

21-
// plan to reset isThrottled after the delay
21+
// настройка сброса isThrottled после задержки
2222
setTimeout(function() {
2323
isThrottled = false;
2424
if (savedArgs) {
25-
// if there were calls, savedThis/savedArgs have the last one
26-
// recursive call runs the function and sets cooldown again
25+
// если были вызовы, последний savedThis/savedArgs
26+
// рекурсивный вызов запускает функцию и снова устанавливает время задержки
2727
wrapper.apply(savedThis, savedArgs);
2828
savedArgs = savedThis = null;
2929
}
3030
}, ms);
3131
}
3232

3333
return wrapper;
34-
}
34+
}

1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/_js.view/test.js

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,37 +11,37 @@ describe("throttle(f, 1000)", function() {
1111
this.clock = sinon.useFakeTimers();
1212
});
1313

14-
it("the first call runs now", function() {
15-
f1000(1); // runs now
14+
it("1-й вызов происходит немедленно", function() {
15+
f1000(1); // вызов происходит немедленно
1616
assert.equal(log, "1");
1717
});
1818

19-
it("then calls are ignored till 1000ms when the last call works", function() {
20-
f1000(2); // (throttling - less than 1000ms since the last run)
21-
f1000(3); // (throttling - less than 1000ms since the last run)
22-
// after 1000 ms f(3) call is scheduled
19+
it("далее вызовы игнорируются до истечения 1000 мс от полседнего вызова", function() {
20+
f1000(2); // (задержка - менее 1000 мс с момента последнего вызов)
21+
f1000(3); // (задержка - менее 1000 мс с момента последнего вызов)
22+
// запланирован вызов спустя f(3) 1000 мс
2323

24-
assert.equal(log, "1"); // right now only the 1st call done
24+
assert.equal(log, "1"); // происходит 1-й вызов
2525

26-
this.clock.tick(1000); // after 1000ms...
27-
assert.equal(log, "13"); // log==13, the call to f1000(3) is made
26+
this.clock.tick(1000); // через 1000 мс...
27+
assert.equal(log, "13"); // log==13, произошел вызов f1000(3)
2828
});
2929

30-
it("the third call waits 1000ms after the second call", function() {
30+
it("3-й вызов ждет 1000 мс от 2-го", function() {
3131
this.clock.tick(100);
32-
f1000(4); // (throttling - less than 1000ms since the last run)
32+
f1000(4); // (задержка - менее 1000 мс с момента последнего вызов)
3333
this.clock.tick(100);
34-
f1000(5); // (throttling - less than 1000ms since the last run)
34+
f1000(5); // (задержка - менее 1000 мс с момента последнего вызов)
3535
this.clock.tick(700);
36-
f1000(6); // (throttling - less than 1000ms since the last run)
36+
f1000(6); // (задержка - менее 1000 мс с момента последнего вызов)
3737

38-
this.clock.tick(100); // now 100 + 100 + 700 + 100 = 1000ms passed
38+
this.clock.tick(100); // теперь прошло 100 + 100 + 700 + 100 = 1000 мс
3939

40-
assert.equal(log, "136"); // the last call was f(6)
40+
assert.equal(log, "136"); // последний вызов был f(6)
4141
});
4242

4343
after(function() {
4444
this.clock.restore();
4545
});
4646

47-
});
47+
});

1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/solution.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,10 @@ function throttle(func, ms) {
3030
}
3131
```
3232

33-
A call to `throttle(func, ms)` returns `wrapper`.
33+
Вызов `throttle(func, ms)` возвращает `wrapper`.
3434

35-
1. During the first call, the `wrapper` just runs `func` and sets the cooldown state (`isThrottled = true`).
36-
2. In this state all calls memorized in `savedArgs/savedThis`. Please note that both the context and the arguments are equally important and should be memorized. We need them simultaneously to reproduce the call.
37-
3. ...Then after `ms` milliseconds pass, `setTimeout` triggers. The cooldown state is removed (`isThrottled = false`). And if we had ignored calls, then `wrapper` is executed with last memorized arguments and context.
35+
1. Во время первого вызова обёртка просто вызывает `func` и устанавливает состояние задержки (`isThrottled = true`).
36+
2. В этом состоянии все вызовы, запоминаются в `saveArgs / saveThis`. Обратите внимание, что контекст и аргументы одинаково важны и должны быть запомнены. Они нам нужны для того, чтобы воспроизвести вызов.
37+
3. ... Затем по прошествии `ms` миллисекунд срабатывает `setTimeout`. Состояние задержки сбрасывается (`isThrottled = false`). И если мы проигнорировали вызовы, то «обёртка» выполняется с последними запомненными аргументами и контекстом.
3838

39-
The 3rd step runs not `func`, but `wrapper`, because we not only need to execute `func`, but once again enter the cooldown state and setup the timeout to reset it.
39+
На третьем шаге выполняется не `func`, а `wrapper`, потому что нам нужно не только выполнить `func`, но и еще раз установить состояние задержки и таймаут для его сброса.
Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,48 @@
1-
importance: 5
1+
важность: 5
22

33
---
44

5-
# Throttle decorator
5+
# Задерживающий декоратор
66

7-
Create a "throttling" decorator `throttle(f, ms)` -- that returns a wrapper, passing the call to `f` at maximum once per `ms` milliseconds. Those calls that fall into the "cooldown" period, are ignored.
7+
Создайте "задерживающий" декоратор `throttle(f, ms)` - который возвращает обёртку, передавая вызов в `f` не более одного раза в `ms` миллисекунд. Те вызовы, которые попадают в период "задержки", игнорируются.
88

9-
**The difference with `debounce` -- if an ignored call is the last during the cooldown, then it executes at the end of the delay.**
9+
**Вариант с `debounce` - если проигнорированный вызов является последним во время "задержки", то он выполняется в конце.**
1010

11-
Let's check the real-life application to better understand that requirement and to see where it comes from.
11+
Давайте рассмотрим реальное приложение, чтобы лучше понять это требование и выяснить, откуда оно взято.
1212

13-
**For instance, we want to track mouse movements.**
13+
**Например, мы хотим отслеживать движения указателя.**
1414

15-
In browser we can setup a function to run at every mouse micro-movement and get the pointer location as it moves. During an active mouse usage, this function usually runs very frequently, can be something like 100 times per second (every 10 ms).
15+
В браузере мы можем объявить функцию, которая будет запускаться при каждом микродвижении указателя и получать его местоположение при каждом его перемещении. Во время активного использования мыши эта функция запускается очень часто, это может происходить около 100 раз в секунду (каждые 10 мс).
1616

17-
**The tracking function should update some information on the web-page.**
17+
**Отслеживающая функция должна обновлять некоторую информацию на веб-странице.**
1818

19-
Updating function `update()` is too heavy to do it on every micro-movement. There is also no sense in making it more often than once per 100ms.
19+
Функция обновления `update()` слишком ресурсоёмкая, чтобы делать это при каждом микродвижении. Также нет смысла делать это чаще, чем один раз в 100 мс.
2020

21-
So we'll assign `throttle(update, 100)` as the function to run on each mouse move instead of the original `update()`. The decorator will be called often, but `update()` will be called at maximum once per 100ms.
21+
Поэтому мы объявим `throttle(update, 100)` как функцию, которая будет запускаться при каждом перемещении указателя вместо оригинальной `update()`. Декоратор будет вызываться часто, но `update()` будет вызываться максимум раз в 100 мс.
2222

23-
Visually, it will look like this:
23+
Визуально это будет выглядеть вот так:
2424

25-
1. For the first mouse movement the decorated variant passes the call to `update`. That's important, the user sees our reaction to their move immediately.
26-
2. Then as the mouse moves on, until `100ms` nothing happens. The decorated variant ignores calls.
27-
3. At the end of `100ms` -- one more `update` happens with the last coordinates.
28-
4. Then, finally, the mouse stops somewhere. The decorated variant waits until `100ms` expire and then runs `update` with last coordinates. So, perhaps the most important, the final mouse coordinates are processed.
25+
1. Для первого движения указателя декорированный вариант передает вызов в `update`. Это важно, т.к. пользователь сразу видит нашу реакцию на его перемещение.
26+
2. Затем, когда указатель продолжает движение, в течение 100 мс ничего не происходит. Декорированный вариант игнорирует вызовы.
27+
3. По истечению 100 мс происходит еще одно «обновление» с последними координатами.
28+
4. Затем, наконец, указатель где-то останавливается. Декорированный вариант ждет, пока не истечет 100 мс и затем вызывает `update` с последними координатами. Так что, пожалуй, самое главное то, что окончательные координаты указателя обработаны.
2929

30-
A code example:
30+
Пример кода:
3131

3232
```js
3333
function f(a) {
3434
console.log(a)
35-
};
35+
}
3636

37-
// f1000 passes calls to f at maximum once per 1000 ms
37+
// f1000 передает вызовы f максимум раз в 1000 мс
3838
let f1000 = throttle(f, 1000);
3939

40-
f1000(1); // shows 1
41-
f1000(2); // (throttling, 1000ms not out yet)
42-
f1000(3); // (throttling, 1000ms not out yet)
40+
f1000(1); // показывает 1
41+
f1000(2); // (ограничение, 1000 мс еще нет)
42+
f1000(3); // (ограничение, 1000 мс еще нет)
4343

44-
// when 1000 ms time out...
45-
// ...outputs 3, intermediate value 2 was ignored
44+
// когда 1000 мс истекли ...
45+
// ...выводим 3, промежуточное значение 2 было проигнорировано
4646
```
4747

48-
P.S. Arguments and the context `this` passed to `f1000` should be passed to the original `f`.
48+
P.S.: Аргументы и контекст `this`, переданные в `f1000`, должны быть переданы в оригинальную `f`.

0 commit comments

Comments
 (0)