UNPKG

1.33 kBJavaScriptView Raw
1var queue = [];
2/**
3 Variable to hold a counting semaphore
4 - Incrementing adds a lock and puts the scheduler in a `suspended` state (if it's not
5 already suspended)
6 - Decrementing releases a lock. Zero locks puts the scheduler in a `released` state. This
7 triggers flushing the queued tasks.
8**/
9var semaphore = 0;
10
11/**
12 Executes a task 'atomically'. Tasks scheduled during this execution will be queued
13 and flushed after this task has finished (assuming the scheduler endup in a released
14 state).
15**/
16function exec(task) {
17 try {
18 suspend();
19 task();
20 } finally {
21 release();
22 }
23}
24
25/**
26 Executes or queues a task depending on the state of the scheduler (`suspended` or `released`)
27**/
28export function asap(task) {
29 queue.push(task);
30
31 if (!semaphore) {
32 suspend();
33 flush();
34 }
35}
36
37/**
38 Puts the scheduler in a `suspended` state. Scheduled tasks will be queued until the
39 scheduler is released.
40**/
41export function suspend() {
42 semaphore++;
43}
44
45/**
46 Puts the scheduler in a `released` state.
47**/
48function release() {
49 semaphore--;
50}
51
52/**
53 Releases the current lock. Executes all queued tasks if the scheduler is in the released state.
54**/
55export function flush() {
56 release();
57
58 var task = void 0;
59 while (!semaphore && (task = queue.shift()) !== undefined) {
60 exec(task);
61 }
62}
\No newline at end of file