100 lines
2.7 KiB
JavaScript
100 lines
2.7 KiB
JavaScript
|
var global = require('../internals/global');
|
||
|
var fails = require('../internals/fails');
|
||
|
var classof = require('../internals/classof-raw');
|
||
|
var bind = require('../internals/bind-context');
|
||
|
var html = require('../internals/html');
|
||
|
var createElement = require('../internals/document-create-element');
|
||
|
|
||
|
var location = global.location;
|
||
|
var set = global.setImmediate;
|
||
|
var clear = global.clearImmediate;
|
||
|
var process = global.process;
|
||
|
var MessageChannel = global.MessageChannel;
|
||
|
var Dispatch = global.Dispatch;
|
||
|
var counter = 0;
|
||
|
var queue = {};
|
||
|
var ONREADYSTATECHANGE = 'onreadystatechange';
|
||
|
var defer, channel, port;
|
||
|
|
||
|
var run = function (id) {
|
||
|
// eslint-disable-next-line no-prototype-builtins
|
||
|
if (queue.hasOwnProperty(id)) {
|
||
|
var fn = queue[id];
|
||
|
delete queue[id];
|
||
|
fn();
|
||
|
}
|
||
|
};
|
||
|
|
||
|
var runner = function (id) {
|
||
|
return function () {
|
||
|
run(id);
|
||
|
};
|
||
|
};
|
||
|
|
||
|
var listener = function (event) {
|
||
|
run(event.data);
|
||
|
};
|
||
|
|
||
|
var post = function (id) {
|
||
|
// old engines have not location.origin
|
||
|
global.postMessage(id + '', location.protocol + '//' + location.host);
|
||
|
};
|
||
|
|
||
|
// Node.js 0.9+ & IE10+ has setImmediate, otherwise:
|
||
|
if (!set || !clear) {
|
||
|
set = function setImmediate(fn) {
|
||
|
var args = [];
|
||
|
var i = 1;
|
||
|
while (arguments.length > i) args.push(arguments[i++]);
|
||
|
queue[++counter] = function () {
|
||
|
// eslint-disable-next-line no-new-func
|
||
|
(typeof fn == 'function' ? fn : Function(fn)).apply(undefined, args);
|
||
|
};
|
||
|
defer(counter);
|
||
|
return counter;
|
||
|
};
|
||
|
clear = function clearImmediate(id) {
|
||
|
delete queue[id];
|
||
|
};
|
||
|
// Node.js 0.8-
|
||
|
if (classof(process) == 'process') {
|
||
|
defer = function (id) {
|
||
|
process.nextTick(runner(id));
|
||
|
};
|
||
|
// Sphere (JS game engine) Dispatch API
|
||
|
} else if (Dispatch && Dispatch.now) {
|
||
|
defer = function (id) {
|
||
|
Dispatch.now(runner(id));
|
||
|
};
|
||
|
// Browsers with MessageChannel, includes WebWorkers
|
||
|
} else if (MessageChannel) {
|
||
|
channel = new MessageChannel();
|
||
|
port = channel.port2;
|
||
|
channel.port1.onmessage = listener;
|
||
|
defer = bind(port.postMessage, port, 1);
|
||
|
// Browsers with postMessage, skip WebWorkers
|
||
|
// IE8 has postMessage, but it's sync & typeof its postMessage is 'object'
|
||
|
} else if (global.addEventListener && typeof postMessage == 'function' && !global.importScripts && !fails(post)) {
|
||
|
defer = post;
|
||
|
global.addEventListener('message', listener, false);
|
||
|
// IE8-
|
||
|
} else if (ONREADYSTATECHANGE in createElement('script')) {
|
||
|
defer = function (id) {
|
||
|
html.appendChild(createElement('script'))[ONREADYSTATECHANGE] = function () {
|
||
|
html.removeChild(this);
|
||
|
run(id);
|
||
|
};
|
||
|
};
|
||
|
// Rest old browsers
|
||
|
} else {
|
||
|
defer = function (id) {
|
||
|
setTimeout(runner(id), 0);
|
||
|
};
|
||
|
}
|
||
|
}
|
||
|
|
||
|
module.exports = {
|
||
|
set: set,
|
||
|
clear: clear
|
||
|
};
|