1 | import { getWindow } from './dom/getWindow';
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 | var Async = (function () {
|
12 |
|
13 | function Async(parent, onError) {
|
14 | this._timeoutIds = null;
|
15 | this._immediateIds = null;
|
16 | this._intervalIds = null;
|
17 | this._animationFrameIds = null;
|
18 | this._isDisposed = false;
|
19 | this._parent = parent || null;
|
20 | this._onErrorHandler = onError;
|
21 | this._noop = function () {
|
22 |
|
23 | };
|
24 | }
|
25 | |
26 |
|
27 |
|
28 | Async.prototype.dispose = function () {
|
29 | var id;
|
30 | this._isDisposed = true;
|
31 | this._parent = null;
|
32 |
|
33 | if (this._timeoutIds) {
|
34 | for (id in this._timeoutIds) {
|
35 | if (this._timeoutIds.hasOwnProperty(id)) {
|
36 | this.clearTimeout(parseInt(id, 10));
|
37 | }
|
38 | }
|
39 | this._timeoutIds = null;
|
40 | }
|
41 |
|
42 | if (this._immediateIds) {
|
43 | for (id in this._immediateIds) {
|
44 | if (this._immediateIds.hasOwnProperty(id)) {
|
45 | this.clearImmediate(parseInt(id, 10));
|
46 | }
|
47 | }
|
48 | this._immediateIds = null;
|
49 | }
|
50 |
|
51 | if (this._intervalIds) {
|
52 | for (id in this._intervalIds) {
|
53 | if (this._intervalIds.hasOwnProperty(id)) {
|
54 | this.clearInterval(parseInt(id, 10));
|
55 | }
|
56 | }
|
57 | this._intervalIds = null;
|
58 | }
|
59 |
|
60 | if (this._animationFrameIds) {
|
61 | for (id in this._animationFrameIds) {
|
62 | if (this._animationFrameIds.hasOwnProperty(id)) {
|
63 | this.cancelAnimationFrame(parseInt(id, 10));
|
64 | }
|
65 | }
|
66 | this._animationFrameIds = null;
|
67 | }
|
68 | };
|
69 | |
70 |
|
71 |
|
72 |
|
73 |
|
74 |
|
75 | Async.prototype.setTimeout = function (callback, duration) {
|
76 | var _this = this;
|
77 | var timeoutId = 0;
|
78 | if (!this._isDisposed) {
|
79 | if (!this._timeoutIds) {
|
80 | this._timeoutIds = {};
|
81 | }
|
82 | timeoutId = setTimeout(function () {
|
83 |
|
84 | try {
|
85 |
|
86 | if (_this._timeoutIds) {
|
87 | delete _this._timeoutIds[timeoutId];
|
88 | }
|
89 | callback.apply(_this._parent);
|
90 | }
|
91 | catch (e) {
|
92 | if (_this._onErrorHandler) {
|
93 | _this._onErrorHandler(e);
|
94 | }
|
95 | }
|
96 | }, duration);
|
97 | this._timeoutIds[timeoutId] = true;
|
98 | }
|
99 | return timeoutId;
|
100 | };
|
101 | |
102 |
|
103 |
|
104 |
|
105 | Async.prototype.clearTimeout = function (id) {
|
106 | if (this._timeoutIds && this._timeoutIds[id]) {
|
107 | clearTimeout(id);
|
108 | delete this._timeoutIds[id];
|
109 | }
|
110 | };
|
111 | |
112 |
|
113 |
|
114 |
|
115 |
|
116 |
|
117 | Async.prototype.setImmediate = function (callback, targetElement) {
|
118 | var _this = this;
|
119 | var immediateId = 0;
|
120 | var win = getWindow(targetElement);
|
121 | if (!this._isDisposed) {
|
122 | if (!this._immediateIds) {
|
123 | this._immediateIds = {};
|
124 | }
|
125 | var setImmediateCallback = function () {
|
126 |
|
127 | try {
|
128 |
|
129 | if (_this._immediateIds) {
|
130 | delete _this._immediateIds[immediateId];
|
131 | }
|
132 | callback.apply(_this._parent);
|
133 | }
|
134 | catch (e) {
|
135 | _this._logError(e);
|
136 | }
|
137 | };
|
138 | immediateId = win.setTimeout(setImmediateCallback, 0);
|
139 | this._immediateIds[immediateId] = true;
|
140 | }
|
141 | return immediateId;
|
142 | };
|
143 | |
144 |
|
145 |
|
146 |
|
147 |
|
148 | Async.prototype.clearImmediate = function (id, targetElement) {
|
149 | var win = getWindow(targetElement);
|
150 | if (this._immediateIds && this._immediateIds[id]) {
|
151 | win.clearTimeout(id);
|
152 | delete this._immediateIds[id];
|
153 | }
|
154 | };
|
155 | |
156 |
|
157 |
|
158 |
|
159 |
|
160 |
|
161 | Async.prototype.setInterval = function (callback, duration) {
|
162 | var _this = this;
|
163 | var intervalId = 0;
|
164 | if (!this._isDisposed) {
|
165 | if (!this._intervalIds) {
|
166 | this._intervalIds = {};
|
167 | }
|
168 | intervalId = setInterval(function () {
|
169 |
|
170 | try {
|
171 | callback.apply(_this._parent);
|
172 | }
|
173 | catch (e) {
|
174 | _this._logError(e);
|
175 | }
|
176 | }, duration);
|
177 | this._intervalIds[intervalId] = true;
|
178 | }
|
179 | return intervalId;
|
180 | };
|
181 | |
182 |
|
183 |
|
184 |
|
185 | Async.prototype.clearInterval = function (id) {
|
186 | if (this._intervalIds && this._intervalIds[id]) {
|
187 | clearInterval(id);
|
188 | delete this._intervalIds[id];
|
189 | }
|
190 | };
|
191 | |
192 |
|
193 |
|
194 |
|
195 |
|
196 |
|
197 |
|
198 |
|
199 |
|
200 |
|
201 |
|
202 |
|
203 |
|
204 |
|
205 |
|
206 | Async.prototype.throttle = function (func, wait, options) {
|
207 | var _this = this;
|
208 | if (this._isDisposed) {
|
209 | return this._noop;
|
210 | }
|
211 | var waitMS = wait || 0;
|
212 | var leading = true;
|
213 | var trailing = true;
|
214 | var lastExecuteTime = 0;
|
215 | var lastResult;
|
216 |
|
217 | var lastArgs;
|
218 | var timeoutId = null;
|
219 | if (options && typeof options.leading === 'boolean') {
|
220 | leading = options.leading;
|
221 | }
|
222 | if (options && typeof options.trailing === 'boolean') {
|
223 | trailing = options.trailing;
|
224 | }
|
225 | var callback = function (userCall) {
|
226 | var now = Date.now();
|
227 | var delta = now - lastExecuteTime;
|
228 | var waitLength = leading ? waitMS - delta : waitMS;
|
229 | if (delta >= waitMS && (!userCall || leading)) {
|
230 | lastExecuteTime = now;
|
231 | if (timeoutId) {
|
232 | _this.clearTimeout(timeoutId);
|
233 | timeoutId = null;
|
234 | }
|
235 | lastResult = func.apply(_this._parent, lastArgs);
|
236 | }
|
237 | else if (timeoutId === null && trailing) {
|
238 | timeoutId = _this.setTimeout(callback, waitLength);
|
239 | }
|
240 | return lastResult;
|
241 | };
|
242 |
|
243 | var resultFunction = (function () {
|
244 | var args = [];
|
245 | for (var _i = 0; _i < arguments.length; _i++) {
|
246 | args[_i] = arguments[_i];
|
247 | }
|
248 | lastArgs = args;
|
249 | return callback(true);
|
250 | });
|
251 | return resultFunction;
|
252 | };
|
253 | |
254 |
|
255 |
|
256 |
|
257 |
|
258 |
|
259 |
|
260 |
|
261 |
|
262 |
|
263 |
|
264 |
|
265 |
|
266 |
|
267 |
|
268 |
|
269 | Async.prototype.debounce = function (func, wait, options) {
|
270 | var _this = this;
|
271 | if (this._isDisposed) {
|
272 | var noOpFunction = (function () {
|
273 |
|
274 | });
|
275 | noOpFunction.cancel = function () {
|
276 | return;
|
277 | };
|
278 | noOpFunction.flush = (function () { return null; });
|
279 | noOpFunction.pending = function () { return false; };
|
280 | return noOpFunction;
|
281 | }
|
282 | var waitMS = wait || 0;
|
283 | var leading = false;
|
284 | var trailing = true;
|
285 | var maxWait = null;
|
286 | var lastCallTime = 0;
|
287 | var lastExecuteTime = Date.now();
|
288 | var lastResult;
|
289 |
|
290 | var lastArgs;
|
291 | var timeoutId = null;
|
292 | if (options && typeof options.leading === 'boolean') {
|
293 | leading = options.leading;
|
294 | }
|
295 | if (options && typeof options.trailing === 'boolean') {
|
296 | trailing = options.trailing;
|
297 | }
|
298 | if (options && typeof options.maxWait === 'number' && !isNaN(options.maxWait)) {
|
299 | maxWait = options.maxWait;
|
300 | }
|
301 | var markExecuted = function (time) {
|
302 | if (timeoutId) {
|
303 | _this.clearTimeout(timeoutId);
|
304 | timeoutId = null;
|
305 | }
|
306 | lastExecuteTime = time;
|
307 | };
|
308 | var invokeFunction = function (time) {
|
309 | markExecuted(time);
|
310 | lastResult = func.apply(_this._parent, lastArgs);
|
311 | };
|
312 | var callback = function (userCall) {
|
313 | var now = Date.now();
|
314 | var executeImmediately = false;
|
315 | if (userCall) {
|
316 | if (leading && now - lastCallTime >= waitMS) {
|
317 | executeImmediately = true;
|
318 | }
|
319 | lastCallTime = now;
|
320 | }
|
321 | var delta = now - lastCallTime;
|
322 | var waitLength = waitMS - delta;
|
323 | var maxWaitDelta = now - lastExecuteTime;
|
324 | var maxWaitExpired = false;
|
325 | if (maxWait !== null) {
|
326 |
|
327 | if (maxWaitDelta >= maxWait && timeoutId) {
|
328 | maxWaitExpired = true;
|
329 | }
|
330 | else {
|
331 | waitLength = Math.min(waitLength, maxWait - maxWaitDelta);
|
332 | }
|
333 | }
|
334 | if (delta >= waitMS || maxWaitExpired || executeImmediately) {
|
335 | invokeFunction(now);
|
336 | }
|
337 | else if ((timeoutId === null || !userCall) && trailing) {
|
338 | timeoutId = _this.setTimeout(callback, waitLength);
|
339 | }
|
340 | return lastResult;
|
341 | };
|
342 | var pending = function () {
|
343 | return !!timeoutId;
|
344 | };
|
345 | var cancel = function () {
|
346 | if (pending()) {
|
347 |
|
348 | markExecuted(Date.now());
|
349 | }
|
350 | };
|
351 | var flush = function () {
|
352 | if (pending()) {
|
353 | invokeFunction(Date.now());
|
354 | }
|
355 | return lastResult;
|
356 | };
|
357 |
|
358 | var resultFunction = (function () {
|
359 | var args = [];
|
360 | for (var _i = 0; _i < arguments.length; _i++) {
|
361 | args[_i] = arguments[_i];
|
362 | }
|
363 | lastArgs = args;
|
364 | return callback(true);
|
365 | });
|
366 | resultFunction.cancel = cancel;
|
367 | resultFunction.flush = flush;
|
368 | resultFunction.pending = pending;
|
369 | return resultFunction;
|
370 | };
|
371 | Async.prototype.requestAnimationFrame = function (callback, targetElement) {
|
372 | var _this = this;
|
373 | var animationFrameId = 0;
|
374 | var win = getWindow(targetElement);
|
375 | if (!this._isDisposed) {
|
376 | if (!this._animationFrameIds) {
|
377 | this._animationFrameIds = {};
|
378 | }
|
379 | var animationFrameCallback = function () {
|
380 | try {
|
381 |
|
382 | if (_this._animationFrameIds) {
|
383 | delete _this._animationFrameIds[animationFrameId];
|
384 | }
|
385 | callback.apply(_this._parent);
|
386 | }
|
387 | catch (e) {
|
388 | _this._logError(e);
|
389 | }
|
390 | };
|
391 | animationFrameId = win.requestAnimationFrame
|
392 | ? win.requestAnimationFrame(animationFrameCallback)
|
393 | : win.setTimeout(animationFrameCallback, 0);
|
394 | this._animationFrameIds[animationFrameId] = true;
|
395 | }
|
396 | return animationFrameId;
|
397 | };
|
398 | Async.prototype.cancelAnimationFrame = function (id, targetElement) {
|
399 | var win = getWindow(targetElement);
|
400 | if (this._animationFrameIds && this._animationFrameIds[id]) {
|
401 | win.cancelAnimationFrame ? win.cancelAnimationFrame(id) : win.clearTimeout(id);
|
402 | delete this._animationFrameIds[id];
|
403 | }
|
404 | };
|
405 |
|
406 | Async.prototype._logError = function (e) {
|
407 | if (this._onErrorHandler) {
|
408 | this._onErrorHandler(e);
|
409 | }
|
410 | };
|
411 | return Async;
|
412 | }());
|
413 | export { Async };
|
414 |
|
\ | No newline at end of file |