1 | let len = 0;
|
2 | let vertxNext;
|
3 | let customSchedulerFn;
|
4 |
|
5 | export var asap = function asap(callback, arg) {
|
6 | queue[len] = callback;
|
7 | queue[len + 1] = arg;
|
8 | len += 2;
|
9 | if (len === 2) {
|
10 |
|
11 |
|
12 |
|
13 | if (customSchedulerFn) {
|
14 | customSchedulerFn(flush);
|
15 | } else {
|
16 | scheduleFlush();
|
17 | }
|
18 | }
|
19 | }
|
20 |
|
21 | export function setScheduler(scheduleFn) {
|
22 | customSchedulerFn = scheduleFn;
|
23 | }
|
24 |
|
25 | export function setAsap(asapFn) {
|
26 | asap = asapFn;
|
27 | }
|
28 |
|
29 | const browserWindow = (typeof window !== 'undefined') ? window : undefined;
|
30 | const browserGlobal = browserWindow || {};
|
31 | const BrowserMutationObserver = browserGlobal.MutationObserver || browserGlobal.WebKitMutationObserver;
|
32 | const isNode = typeof self === 'undefined' && typeof process !== 'undefined' && {}.toString.call(process) === '[object process]';
|
33 |
|
34 |
|
35 | const isWorker = typeof Uint8ClampedArray !== 'undefined' &&
|
36 | typeof importScripts !== 'undefined' &&
|
37 | typeof MessageChannel !== 'undefined';
|
38 |
|
39 |
|
40 | function useNextTick() {
|
41 |
|
42 |
|
43 | return () => process.nextTick(flush);
|
44 | }
|
45 |
|
46 |
|
47 | function useVertxTimer() {
|
48 | if (typeof vertxNext !== 'undefined') {
|
49 | return function() {
|
50 | vertxNext(flush);
|
51 | };
|
52 | }
|
53 |
|
54 | return useSetTimeout();
|
55 | }
|
56 |
|
57 | function useMutationObserver() {
|
58 | let iterations = 0;
|
59 | const observer = new BrowserMutationObserver(flush);
|
60 | const node = document.createTextNode('');
|
61 | observer.observe(node, { characterData: true });
|
62 |
|
63 | return () => {
|
64 | node.data = (iterations = ++iterations % 2);
|
65 | };
|
66 | }
|
67 |
|
68 |
|
69 | function useMessageChannel() {
|
70 | const channel = new MessageChannel();
|
71 | channel.port1.onmessage = flush;
|
72 | return () => channel.port2.postMessage(0);
|
73 | }
|
74 |
|
75 | function useSetTimeout() {
|
76 |
|
77 |
|
78 | const globalSetTimeout = setTimeout;
|
79 | return () => globalSetTimeout(flush, 1);
|
80 | }
|
81 |
|
82 | const queue = new Array(1000);
|
83 | function flush() {
|
84 | for (let i = 0; i < len; i+=2) {
|
85 | let callback = queue[i];
|
86 | let arg = queue[i+1];
|
87 |
|
88 | callback(arg);
|
89 |
|
90 | queue[i] = undefined;
|
91 | queue[i+1] = undefined;
|
92 | }
|
93 |
|
94 | len = 0;
|
95 | }
|
96 |
|
97 | function attemptVertx() {
|
98 | try {
|
99 | const vertx = Function('return this')().require('vertx');
|
100 | vertxNext = vertx.runOnLoop || vertx.runOnContext;
|
101 | return useVertxTimer();
|
102 | } catch(e) {
|
103 | return useSetTimeout();
|
104 | }
|
105 | }
|
106 |
|
107 | let scheduleFlush;
|
108 |
|
109 | if (isNode) {
|
110 | scheduleFlush = useNextTick();
|
111 | } else if (BrowserMutationObserver) {
|
112 | scheduleFlush = useMutationObserver();
|
113 | } else if (isWorker) {
|
114 | scheduleFlush = useMessageChannel();
|
115 | } else if (browserWindow === undefined && typeof require === 'function') {
|
116 | scheduleFlush = attemptVertx();
|
117 | } else {
|
118 | scheduleFlush = useSetTimeout();
|
119 | }
|