UNPKG

3.44 kBJavaScriptView Raw
1'use strict';
2var global = require('../internals/global');
3var apply = require('../internals/function-apply');
4var bind = require('../internals/function-bind-context');
5var isCallable = require('../internals/is-callable');
6var hasOwn = require('../internals/has-own-property');
7var fails = require('../internals/fails');
8var html = require('../internals/html');
9var arraySlice = require('../internals/array-slice');
10var createElement = require('../internals/document-create-element');
11var validateArgumentsLength = require('../internals/validate-arguments-length');
12var IS_IOS = require('../internals/engine-is-ios');
13var IS_NODE = require('../internals/engine-is-node');
14
15var set = global.setImmediate;
16var clear = global.clearImmediate;
17var process = global.process;
18var Dispatch = global.Dispatch;
19var Function = global.Function;
20var MessageChannel = global.MessageChannel;
21var String = global.String;
22var counter = 0;
23var queue = {};
24var ONREADYSTATECHANGE = 'onreadystatechange';
25var $location, defer, channel, port;
26
27fails(function () {
28 // Deno throws a ReferenceError on `location` access without `--location` flag
29 $location = global.location;
30});
31
32var run = function (id) {
33 if (hasOwn(queue, id)) {
34 var fn = queue[id];
35 delete queue[id];
36 fn();
37 }
38};
39
40var runner = function (id) {
41 return function () {
42 run(id);
43 };
44};
45
46var eventListener = function (event) {
47 run(event.data);
48};
49
50var globalPostMessageDefer = function (id) {
51 // old engines have not location.origin
52 global.postMessage(String(id), $location.protocol + '//' + $location.host);
53};
54
55// Node.js 0.9+ & IE10+ has setImmediate, otherwise:
56if (!set || !clear) {
57 set = function setImmediate(handler) {
58 validateArgumentsLength(arguments.length, 1);
59 var fn = isCallable(handler) ? handler : Function(handler);
60 var args = arraySlice(arguments, 1);
61 queue[++counter] = function () {
62 apply(fn, undefined, args);
63 };
64 defer(counter);
65 return counter;
66 };
67 clear = function clearImmediate(id) {
68 delete queue[id];
69 };
70 // Node.js 0.8-
71 if (IS_NODE) {
72 defer = function (id) {
73 process.nextTick(runner(id));
74 };
75 // Sphere (JS game engine) Dispatch API
76 } else if (Dispatch && Dispatch.now) {
77 defer = function (id) {
78 Dispatch.now(runner(id));
79 };
80 // Browsers with MessageChannel, includes WebWorkers
81 // except iOS - https://github.com/zloirock/core-js/issues/624
82 } else if (MessageChannel && !IS_IOS) {
83 channel = new MessageChannel();
84 port = channel.port2;
85 channel.port1.onmessage = eventListener;
86 defer = bind(port.postMessage, port);
87 // Browsers with postMessage, skip WebWorkers
88 // IE8 has postMessage, but it's sync & typeof its postMessage is 'object'
89 } else if (
90 global.addEventListener &&
91 isCallable(global.postMessage) &&
92 !global.importScripts &&
93 $location && $location.protocol !== 'file:' &&
94 !fails(globalPostMessageDefer)
95 ) {
96 defer = globalPostMessageDefer;
97 global.addEventListener('message', eventListener, false);
98 // IE8-
99 } else if (ONREADYSTATECHANGE in createElement('script')) {
100 defer = function (id) {
101 html.appendChild(createElement('script'))[ONREADYSTATECHANGE] = function () {
102 html.removeChild(this);
103 run(id);
104 };
105 };
106 // Rest old browsers
107 } else {
108 defer = function (id) {
109 setTimeout(runner(id), 0);
110 };
111 }
112}
113
114module.exports = {
115 set: set,
116 clear: clear
117};