1 | import { Scheduler } from '../Scheduler';
|
---|
2 | import { Action } from './Action';
|
---|
3 | import { AsyncAction } from './AsyncAction';
|
---|
4 | import { SchedulerAction } from '../types';
|
---|
5 | import { Subscription } from '../Subscription';
|
---|
6 |
|
---|
7 | export class AsyncScheduler extends Scheduler {
|
---|
8 | public static delegate?: Scheduler;
|
---|
9 | public actions: Array<AsyncAction<any>> = [];
|
---|
10 | /**
|
---|
11 | * A flag to indicate whether the Scheduler is currently executing a batch of
|
---|
12 | * queued actions.
|
---|
13 | * @type {boolean}
|
---|
14 | * @deprecated internal use only
|
---|
15 | */
|
---|
16 | public active: boolean = false;
|
---|
17 | /**
|
---|
18 | * An internal ID used to track the latest asynchronous task such as those
|
---|
19 | * coming from `setTimeout`, `setInterval`, `requestAnimationFrame`, and
|
---|
20 | * others.
|
---|
21 | * @type {any}
|
---|
22 | * @deprecated internal use only
|
---|
23 | */
|
---|
24 | public scheduled: any = undefined;
|
---|
25 |
|
---|
26 | constructor(SchedulerAction: typeof Action,
|
---|
27 | now: () => number = Scheduler.now) {
|
---|
28 | super(SchedulerAction, () => {
|
---|
29 | if (AsyncScheduler.delegate && AsyncScheduler.delegate !== this) {
|
---|
30 | return AsyncScheduler.delegate.now();
|
---|
31 | } else {
|
---|
32 | return now();
|
---|
33 | }
|
---|
34 | });
|
---|
35 | }
|
---|
36 |
|
---|
37 | public schedule<T>(work: (this: SchedulerAction<T>, state?: T) => void, delay: number = 0, state?: T): Subscription {
|
---|
38 | if (AsyncScheduler.delegate && AsyncScheduler.delegate !== this) {
|
---|
39 | return AsyncScheduler.delegate.schedule(work, delay, state);
|
---|
40 | } else {
|
---|
41 | return super.schedule(work, delay, state);
|
---|
42 | }
|
---|
43 | }
|
---|
44 |
|
---|
45 | public flush(action: AsyncAction<any>): void {
|
---|
46 |
|
---|
47 | const {actions} = this;
|
---|
48 |
|
---|
49 | if (this.active) {
|
---|
50 | actions.push(action);
|
---|
51 | return;
|
---|
52 | }
|
---|
53 |
|
---|
54 | let error: any;
|
---|
55 | this.active = true;
|
---|
56 |
|
---|
57 | do {
|
---|
58 | if (error = action.execute(action.state, action.delay)) {
|
---|
59 | break;
|
---|
60 | }
|
---|
61 | } while (action = actions.shift()); // exhaust the scheduler queue
|
---|
62 |
|
---|
63 | this.active = false;
|
---|
64 |
|
---|
65 | if (error) {
|
---|
66 | while (action = actions.shift()) {
|
---|
67 | action.unsubscribe();
|
---|
68 | }
|
---|
69 | throw error;
|
---|
70 | }
|
---|
71 | }
|
---|
72 | }
|
---|