Skip to content

Instantly share code, notes, and snippets.

@lac5
Created June 13, 2019 19:56
Show Gist options
  • Save lac5/fd86a4a6e0a9f4c76939435422e5dabd to your computer and use it in GitHub Desktop.
Save lac5/fd86a4a6e0a9f4c76939435422e5dabd to your computer and use it in GitHub Desktop.
A function that cuts down potentially long or infinite loops to prevent blocking the event loop.
/**
* Cuts down potentially long or infinite loops to prevent blocking the event loop.
*
* Example:
* snip(10, 500, function*() {
* for (let i = 0; i < 1e100; i++, yield) {
* console.log(i);
* }
* console.log('Done!');
* });
*
* let check = false;
* snip(1, 1000, function*() {
* while (!check) {
* console.log('check = false');
* yield;
* }
* console.log('Done!');
* });
* setTimeout(() => check = true, 10000);
*
* @param {number} interval The number of times that `yield` will be called until it times out.
* @param {number} cooldown The amount of time in milliseconds between each interval.
* @param {function*(): any} gen The generator function. Each `yield` gives the current count within the interval (from 0 to interval).
* @return {Promise<any>} Gives the return value of gen.
*/
function snip(interval, cooldown, gen) {
return new Promise(function(resolve, reject) {
let g = gen(), v, i;
setTimeout(function loop() {
try {
for (i = 0; i < interval; i++) {
v = g.next(i);
if (v.done) {
this.ended = true;
resolve(v.value);
return;
}
}
setTimeout(loop, cooldown);
} catch (e) {
reject(e);
}
}, 0);
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment