1+ /*
2+
3+ Interval Cancellation
4+ Easy
5+ premium lock icon
6+ Companies
7+ Given a function fn, an array of arguments args, and an interval time t, return a cancel function cancelFn.
8+
9+ After a delay of cancelTimeMs, the returned cancel function cancelFn will be invoked.
10+
11+ setTimeout(cancelFn, cancelTimeMs)
12+ The function fn should be called with args immediately and then called again every t milliseconds until cancelFn is called at cancelTimeMs ms.
13+
14+
15+
16+ Example 1:
17+
18+ Input: fn = (x) => x * 2, args = [4], t = 35
19+ Output:
20+ [
21+ {"time": 0, "returned": 8},
22+ {"time": 35, "returned": 8},
23+ {"time": 70, "returned": 8},
24+ {"time": 105, "returned": 8},
25+ {"time": 140, "returned": 8},
26+ {"time": 175, "returned": 8}
27+ ]
28+ Explanation:
29+ const cancelTimeMs = 190;
30+ const cancelFn = cancellable((x) => x * 2, [4], 35);
31+ setTimeout(cancelFn, cancelTimeMs);
32+
33+ Every 35ms, fn(4) is called. Until t=190ms, then it is cancelled.
34+ 1st fn call is at 0ms. fn(4) returns 8.
35+ 2nd fn call is at 35ms. fn(4) returns 8.
36+ 3rd fn call is at 70ms. fn(4) returns 8.
37+ 4th fn call is at 105ms. fn(4) returns 8.
38+ 5th fn call is at 140ms. fn(4) returns 8.
39+ 6th fn call is at 175ms. fn(4) returns 8.
40+ Cancelled at 190ms
41+ Example 2:
42+
43+ Input: fn = (x1, x2) => (x1 * x2), args = [2, 5], t = 30
44+ Output:
45+ [
46+ {"time": 0, "returned": 10},
47+ {"time": 30, "returned": 10},
48+ {"time": 60, "returned": 10},
49+ {"time": 90, "returned": 10},
50+ {"time": 120, "returned": 10},
51+ {"time": 150, "returned": 10}
52+ ]
53+ Explanation:
54+ const cancelTimeMs = 165;
55+ const cancelFn = cancellable((x1, x2) => (x1 * x2), [2, 5], 30)
56+ setTimeout(cancelFn, cancelTimeMs)
57+
58+ Every 30ms, fn(2, 5) is called. Until t=165ms, then it is cancelled.
59+ 1st fn call is at 0ms
60+ 2nd fn call is at 30ms
61+ 3rd fn call is at 60ms
62+ 4th fn call is at 90ms
63+ 5th fn call is at 120ms
64+ 6th fn call is at 150ms
65+ Cancelled at 165ms
66+ Example 3:
67+
68+ Input: fn = (x1, x2, x3) => (x1 + x2 + x3), args = [5, 1, 3], t = 50
69+ Output:
70+ [
71+ {"time": 0, "returned": 9},
72+ {"time": 50, "returned": 9},
73+ {"time": 100, "returned": 9},
74+ {"time": 150, "returned": 9}
75+ ]
76+ Explanation:
77+ const cancelTimeMs = 180;
78+ const cancelFn = cancellable((x1, x2, x3) => (x1 + x2 + x3), [5, 1, 3], 50)
79+ setTimeout(cancelFn, cancelTimeMs)
80+
81+ Every 50ms, fn(5, 1, 3) is called. Until t=180ms, then it is cancelled.
82+ 1st fn call is at 0ms
83+ 2nd fn call is at 50ms
84+ 3rd fn call is at 100ms
85+ 4th fn call is at 150ms
86+ Cancelled at 180ms
87+
88+
89+ Constraints:
90+
91+ fn is a function
92+ args is a valid JSON array
93+ 1 <= args.length <= 10
94+ 30 <= t <= 100
95+ 10 <= cancelTimeMs <= 500
96+
97+
98+ */
99+
100+
101+ type JSONValue = null | boolean | number | string | JSONValue [ ] | { [ key : string ] : JSONValue } ;
102+ type Fn = ( ...args : JSONValue [ ] ) => void ;
103+
104+ function cancellable ( fn : Fn , args : JSONValue [ ] , t : number ) : ( ) => void {
105+
106+ fn ( ...args ) ;
107+
108+ const invId = setInterval ( ( ) => {
109+ fn ( ...args ) ;
110+ } , t ) ;
111+
112+ return ( ) => clearInterval ( invId ) ;
113+ }
114+ /**
115+ * const result = [];
116+ *
117+ * const fn = (x) => x * 2;
118+ * const args = [4], t = 35, cancelTimeMs = 190;
119+ *
120+ * const start = performance.now();
121+ *
122+ * const log = (...argsArr) => {
123+ * const diff = Math.floor(performance.now() - start);
124+ * result.push({"time": diff, "returned": fn(...argsArr)});
125+ * }
126+ *
127+ * const cancel = cancellable(log, args, t);
128+ *
129+ * setTimeout(cancel, cancelTimeMs);
130+ *
131+ * setTimeout(() => {
132+ * console.log(result); // [
133+ * // {"time":0,"returned":8},
134+ * // {"time":35,"returned":8},
135+ * // {"time":70,"returned":8},
136+ * // {"time":105,"returned":8},
137+ * // {"time":140,"returned":8},
138+ * // {"time":175,"returned":8}
139+ * // ]
140+ * }, cancelTimeMs + t + 15)
141+ */
0 commit comments