forked from codesandbox/codesandbox-client
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsetImmediate.ts
More file actions
69 lines (67 loc) · 2.05 KB
/
setImmediate.ts
File metadata and controls
69 lines (67 loc) · 2.05 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
import global from '../core/global';
/**
* @hidden
*/
let bfsSetImmediate: (cb: Function, ...args: any[]) => any;
if (typeof(setImmediate) !== "undefined") {
bfsSetImmediate = setImmediate;
} else {
const gScope = global;
const timeouts: ({ fn: (...args: any[]) => void, args: any[] })[] = [];
const messageName = "zero-timeout-message";
const canUsePostMessage = function() {
if (typeof gScope.importScripts !== 'undefined' || !gScope.postMessage) {
return false;
}
let postMessageIsAsync = true;
const oldOnMessage = gScope.onmessage;
gScope.onmessage = function() {
postMessageIsAsync = false;
};
gScope.postMessage('', '*');
gScope.onmessage = oldOnMessage;
return postMessageIsAsync;
};
if (canUsePostMessage()) {
bfsSetImmediate = function(fn: () => void, ...args: any[]) {
timeouts.push({ fn, args });
gScope.postMessage(messageName, "*");
};
const handleMessage = function(event: MessageEvent) {
if (event.source === self && event.data === messageName) {
if (event.stopPropagation) {
event.stopPropagation();
} else {
event.cancelBubble = true;
}
if (timeouts.length > 0) {
const { fn, args } = timeouts.shift()!;
return fn(...args);
}
}
};
if (gScope.addEventListener) {
gScope.addEventListener('message', handleMessage, true);
} else {
gScope.attachEvent('onmessage', handleMessage);
}
} else if (gScope.MessageChannel) {
// WebWorker MessageChannel
const channel = new gScope.MessageChannel();
channel.port1.onmessage = (event: any) => {
if (timeouts.length > 0) {
const { fn, args } = timeouts.shift()!;
return fn(...args);
}
};
bfsSetImmediate = (fn: () => void, ...args: any[]) => {
timeouts.push({ fn, args });
channel.port2.postMessage('');
};
} else {
bfsSetImmediate = function(fn: () => void, ...args: any[]) {
return setTimeout(fn, 0, ...args);
};
}
}
export default bfsSetImmediate;