Last active
January 19, 2021 07:31
-
-
Save rkatic/4695131 to your computer and use it in GitHub Desktop.
Cross-browser and optimized way to postpone a function execution to next "tick".
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Based on the Q.nextTick implementation https://github.com/kriskowal/q/pull/195. | |
var later = (function(){ | |
var head = { task: void 0, next: null }, tail = head, | |
maxPendingTicks = 2, pendingTicks = 0, queuedTasks = 0, usedTicks = 0, | |
requestTick; | |
var onTick = function() { | |
--pendingTicks; | |
if ( ++usedTicks >= maxPendingTicks ) { | |
// Amortize delay after thrown exceptions. | |
maxPendingTicks *= 2; | |
var expectedTicks = queuedTasks && Math.min( queuedTasks - 1, maxPendingTicks ); | |
while ( pendingTicks < expectedTicks ) { | |
++pendingTicks; | |
requestTick(); | |
} | |
usedTicks = 0; | |
} | |
while ( queuedTasks ) { | |
--queuedTasks; // decrement here to ensure it's never negative | |
head = head.next; | |
var task = head.task; | |
head.task = void 0; | |
task(); | |
} | |
usedTicks = 0; | |
}; | |
var later = function( task ) { | |
tail = tail.next = { task: task, next: null }; | |
if ( ++queuedTasks > pendingTicks && pendingTicks < maxPendingTicks ) { | |
++pendingTicks; | |
requestTick(); | |
} | |
}; | |
var win = typeof window !== "undefined" && window; | |
if ( typeof process !== "undefined" && "nextTick" in process ) { | |
requestTick = function() { | |
process.nextTick( onTick ); | |
}; | |
} else if ( typeof win.setImmediate === "function" ) { | |
requestTick = function() { | |
win.setImmediate( onTick ); | |
}; | |
} else if ( typeof MessageChannel !== "undefined" ) { | |
var channel = new MessageChannel(); | |
channel.port1.onmessage = onTick; | |
requestTick = function() { | |
channel.port2.postMessage(0); | |
}; | |
} else { | |
requestTick = function() { | |
setTimeout( onTick, 0 ); | |
}; | |
if ( win && typeof Image !== "undefined" ) { | |
var c = 0; | |
var requestTickViaImage = function( cb ) { | |
var img = new Image(); | |
img.onerror = cb || onTick; | |
img.src = 'data:image/png,'; | |
}; | |
try { | |
requestTickViaImage(function() { | |
if ( --c === 0 ) { | |
requestTick = requestTickViaImage; | |
} | |
}); | |
++c; | |
} catch (e) {} | |
c && setTimeout(function() { | |
c = 0; | |
}, 0); | |
} | |
} | |
return later; | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment