|
1 | 1 | let nextHandle = 1;
|
| 2 | +const RESOLVED = (() => Promise.resolve())(); |
| 3 | +const activeHandles: { [key: number]: any } = {}; |
2 | 4 |
|
3 |
| -const tasksByHandle: { [handle: string]: () => void } = {}; |
4 |
| - |
5 |
| -function runIfPresent(handle: number) { |
6 |
| - const cb = tasksByHandle[handle]; |
7 |
| - if (cb) { |
8 |
| - cb(); |
| 5 | +/** |
| 6 | + * Finds the handle in the list of active handles, and removes it. |
| 7 | + * Returns `true` if found, `false` otherwise. Used both to clear |
| 8 | + * Immediate scheduled tasks, and to identify if a task should be scheduled. |
| 9 | + */ |
| 10 | +function findAndClearHandle(handle: number): boolean { |
| 11 | + if (handle in activeHandles) { |
| 12 | + delete activeHandles[handle]; |
| 13 | + return true; |
9 | 14 | }
|
| 15 | + return false; |
10 | 16 | }
|
11 | 17 |
|
| 18 | +/** |
| 19 | + * Helper functions to schedule and unschedule microtasks. |
| 20 | + */ |
12 | 21 | export const Immediate = {
|
13 | 22 | setImmediate(cb: () => void): number {
|
14 | 23 | const handle = nextHandle++;
|
15 |
| - tasksByHandle[handle] = cb; |
16 |
| - Promise.resolve().then(() => runIfPresent(handle)); |
| 24 | + activeHandles[handle] = true; |
| 25 | + RESOLVED.then(() => findAndClearHandle(handle) && cb()); |
17 | 26 | return handle;
|
18 | 27 | },
|
19 | 28 |
|
20 | 29 | clearImmediate(handle: number): void {
|
21 |
| - delete tasksByHandle[handle]; |
| 30 | + findAndClearHandle(handle); |
22 | 31 | },
|
23 | 32 | };
|
| 33 | + |
| 34 | +/** |
| 35 | + * Used for internal testing purposes only. Do not export from library. |
| 36 | + */ |
| 37 | +export const TestTools = { |
| 38 | + pending() { |
| 39 | + return Object.keys(activeHandles).length; |
| 40 | + } |
| 41 | +}; |
0 commit comments