-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path2676-Throttle.js
More file actions
95 lines (86 loc) · 4.23 KB
/
2676-Throttle.js
File metadata and controls
95 lines (86 loc) · 4.23 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
// 2676. Throttle
// Given a function fn and a time in milliseconds t, return a throttled version of that function.
// A throttled function is first called without delay and then, for a time interval of t milliseconds,
// can't be executed but should store the latest function arguments provided to call fn with them after the end of the delay.
// For instance, t = 50ms, and the function was called at 30ms, 40ms, and 60ms.
// The first function call would block calling functions for the following t milliseconds.
// The second function call would save arguments, and the third call arguments should overwrite currently stored arguments from the second call because the second and third calls are called before 80ms.
// Once the delay has passed, the throttled function should be called with the latest arguments provided during the delay period, and it should also create another delay period of 80ms + t.
// Throttle DiagramThe above diagram shows how throttle will transform events.
// Each rectangle represents 100ms and the throttle time is 400ms. Each color represents a different set of inputs.
// Example 1:
// Input:
// t = 100,
// calls = [
// {"t":20,"inputs":[1]}
// ]
// Output: [{"t":20,"inputs":[1]}]
// Explanation: The 1st call is always called without delay
// Example 2:
// Input:
// t = 50,
// calls = [
// {"t":50,"inputs":[1]},
// {"t":75,"inputs":[2]}
// ]
// Output: [{"t":50,"inputs":[1]},{"t":100,"inputs":[2]}]
// Explanation:
// The 1st is called a function with arguments (1) without delay.
// The 2nd is called at 75ms, within the delay period because 50ms + 50ms = 100ms, so the next call can be reached at 100ms. Therefore, we save arguments from the 2nd call to use them at the callback of the 1st call.
// Example 3:
// Input:
// t = 70,
// calls = [
// {"t":50,"inputs":[1]},
// {"t":75,"inputs":[2]},
// {"t":90,"inputs":[8]},
// {"t": 140, "inputs":[5,7]},
// {"t": 300, "inputs": [9,4]}
// ]
// Output: [{"t":50,"inputs":[1]},{"t":120,"inputs":[8]},{"t":190,"inputs":[5,7]},{"t":300,"inputs":[9,4]}]
// Explanation:
// The 1st is called a function with arguments (1) without delay.
// The 2nd is called at 75ms within the delay period because 50ms + 70ms = 120ms, so it should only save arguments.
// The 3rd is also called within the delay period, and because we need just the latest function arguments, we overwrite previous ones. After the delay period, we do a callback at 120ms with saved arguments. That callback makes another delay period of 120ms + 70ms = 190ms so that the next function can be called at 190ms.
// The 4th is called at 140ms in the delay period, so it should be called as a callback at 190ms. That will create another delay period of 190ms + 70ms = 260ms.
// The 5th is called at 300ms, but it is after 260ms, so it should be called immediately and should create another delay period of 300ms + 70ms = 370ms.
// Constraints:
// 0 <= t <= 1000
// 1 <= calls.length <= 10
// 0 <= calls[i].t <= 1000
// 0 <= calls[i].inputs[j], calls[i].inputs.length <= 10
/**
* @param {Function} fn
* @param {number} t
* @return {Function}
*/
var throttle = function(fn, t) {
// let timer = null;
// return function(...args) {
// if(timer !== null) return false;
// fn(...args);
// timer = setTimeout(() => clearTimeout(timer), t)
// }
let timer = null;
let last = 0;
return function(...args) {
// 如果 fn 在一段时间内没有被调用,延迟会变成负数
// 在那种情况下,我们应该立即调用 fn(延迟是 0)
const delay = Math.max(0, last - Date.now());
// 在创建新的超时之前,我们需要清除现有的超时(如果存在)。这样,在任何给定的时间,最多只有一个超时在运行
clearTimeout(timer);
timer = setTimeout(() => {
fn(...args);
// 再次调用时使用这个来判读需不需要继续执行
last = Date.now() + t;
}, delay);
}
};
/**
* const throttled = throttle(console.log, 100);
* throttled("log"); // logged immediately.
* throttled("log"); // logged at t=100ms.
*/
const throttled = throttle(console.log, 100);
throttled("log"); // logged immediately.
throttled("log"); // logged at t=100ms.