Created
June 13, 2019 19:56
-
-
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.
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
/** | |
* 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