97 lines
1.9 KiB
JavaScript
97 lines
1.9 KiB
JavaScript
|
'use strict';
|
||
|
var types = [
|
||
|
require('./nextTick'),
|
||
|
require('./mutation.js'),
|
||
|
require('./messageChannel'),
|
||
|
require('./stateChange'),
|
||
|
require('./timeout')
|
||
|
];
|
||
|
var draining;
|
||
|
var currentQueue;
|
||
|
var queueIndex = -1;
|
||
|
var queue = [];
|
||
|
var scheduled = false;
|
||
|
function cleanUpNextTick() {
|
||
|
if (!draining || !currentQueue) {
|
||
|
return;
|
||
|
}
|
||
|
draining = false;
|
||
|
if (currentQueue.length) {
|
||
|
queue = currentQueue.concat(queue);
|
||
|
} else {
|
||
|
queueIndex = -1;
|
||
|
}
|
||
|
if (queue.length) {
|
||
|
nextTick();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//named nextTick for less confusing stack traces
|
||
|
function nextTick() {
|
||
|
if (draining) {
|
||
|
return;
|
||
|
}
|
||
|
scheduled = false;
|
||
|
draining = true;
|
||
|
var len = queue.length;
|
||
|
var timeout = setTimeout(cleanUpNextTick);
|
||
|
while (len) {
|
||
|
currentQueue = queue;
|
||
|
queue = [];
|
||
|
while (currentQueue && ++queueIndex < len) {
|
||
|
currentQueue[queueIndex].run();
|
||
|
}
|
||
|
queueIndex = -1;
|
||
|
len = queue.length;
|
||
|
}
|
||
|
currentQueue = null;
|
||
|
queueIndex = -1;
|
||
|
draining = false;
|
||
|
clearTimeout(timeout);
|
||
|
}
|
||
|
var scheduleDrain;
|
||
|
var i = -1;
|
||
|
var len = types.length;
|
||
|
while (++i < len) {
|
||
|
if (types[i] && types[i].test && types[i].test()) {
|
||
|
scheduleDrain = types[i].install(nextTick);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
// v8 likes predictible objects
|
||
|
function Item(fun, array) {
|
||
|
this.fun = fun;
|
||
|
this.array = array;
|
||
|
}
|
||
|
Item.prototype.run = function () {
|
||
|
var fun = this.fun;
|
||
|
var array = this.array;
|
||
|
switch (array.length) {
|
||
|
case 0:
|
||
|
return fun();
|
||
|
case 1:
|
||
|
return fun(array[0]);
|
||
|
case 2:
|
||
|
return fun(array[0], array[1]);
|
||
|
case 3:
|
||
|
return fun(array[0], array[1], array[2]);
|
||
|
default:
|
||
|
return fun.apply(null, array);
|
||
|
}
|
||
|
|
||
|
};
|
||
|
module.exports = immediate;
|
||
|
function immediate(task) {
|
||
|
var args = new Array(arguments.length - 1);
|
||
|
if (arguments.length > 1) {
|
||
|
for (var i = 1; i < arguments.length; i++) {
|
||
|
args[i - 1] = arguments[i];
|
||
|
}
|
||
|
}
|
||
|
queue.push(new Item(task, args));
|
||
|
if (!scheduled && !draining) {
|
||
|
scheduled = true;
|
||
|
scheduleDrain();
|
||
|
}
|
||
|
}
|