Last active
November 1, 2025 17:05
-
-
Save anonhostpi/681dd3eb4cf9601f103f9d226bc22a64 to your computer and use it in GitHub Desktop.
Unlazy a JS Generator Function
This file contains hidden or 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
| // primes the generator function from arguments provided up to the first yield | |
| // no priming performed without arguments/initial call | |
| export default function unlazy(lazyGeneratorFunction) { | |
| const generatorProxy = function (...args) { | |
| const lazy = lazyGeneratorFunction.apply(this, args); | |
| const first = lazy.next(); // run up to first yield | |
| // create a proxy generator that replays that first result once | |
| let sentFirst = false; | |
| const proxy = { | |
| next(value) { | |
| if (!sentFirst) { | |
| sentFirst = true; | |
| return first; | |
| } | |
| return lazy.next(value); | |
| }, | |
| return(value) { | |
| return lazy.return(value); | |
| }, | |
| throw(err) { | |
| return lazy.throw(err); | |
| }, | |
| [Symbol.iterator]() { | |
| return this; | |
| } | |
| }; | |
| Object.setPrototypeOf(proxy, Object.getPrototypeOf(lazy)); | |
| return proxy; | |
| }; | |
| Object.setPrototypeOf(generatorProxy, Object.getPrototypeOf(lazyGeneratorFunction)); | |
| return generatorProxy; | |
| } | |
| export { unlazy } | |
| /* | |
| Usage: | |
| function* lazy(arg1, arg2) { | |
| console.log("priming with", arg1, arg2); | |
| const result = yield arg1 + arg2; | |
| console.log("resumed with", result); | |
| return result * 2; | |
| } | |
| const ul = unlazy(lazy); | |
| // straight iteration results in the same behavior. No difference in priming here: | |
| for (const value of lazy(2, 3)) { | |
| console.log("value:", value); | |
| } | |
| for (const value of ul(2, 3)) { | |
| console.log("value:", value); | |
| } | |
| // the difference comes when the iterator is created before actual iteration: | |
| const it1 = lazy(5, 7); // not primed yet | |
| const it2 = ul(5, 7); // primed immediately | |
| for (const value of it1) { // primes now | |
| console.log("value:", value); | |
| } | |
| for (const value of it2) { // primed already | |
| console.log("value:", value); | |
| } | |
| */ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment