Created
December 6, 2015 03:04
-
-
Save dtothefp/13843cfb7e257c246e1f to your computer and use it in GitHub Desktop.
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
/** | |
* Go one step further and create a `run` function that takes a `generator` function | |
* as it's only argument | |
* https://strongloop.com/strongblog/how-to-generators-node-js-yield-use-cases/ | |
* | |
* a) `run` caches the generator object | |
* b) contains a private `_next` function that initially starts the generator | |
* c) `_next` also acts as the callback to the Node callback signature (i.e. (err, data) => {}) | |
* - first time around it obtains the "thunkified" function from `yield` | |
* - `_next` is then called recursively by the "thunked" function | |
* - `_next` also advances the generator so the data from the cb is returned from `yield` | |
* - the whole process happens over and over if there are multiple yields | |
*/ | |
function run(genFn) { | |
const it = genFn(); | |
function _next(err, val) { | |
if (err) it.throw(err); //throw err to be caught in generator | |
//get the generator object | |
//a) the first time through val === undefined as yield returns what is returned from the thunk | |
//b) next time through `val` will be the value passed as the second arg to the | |
// node callback signature | |
// - essentially this will "dependency inject" the async value from the `yield` | |
const cont = it.next(val); | |
if (cont.done) return; | |
const cb = cont.value; //yielded function from thunk that takes a callback as only arg | |
//call the callback which exposes data inside the generator | |
//the "confusing" part is that `_next` is the cb passed as the second arg to `fs.readFile` or whatever is "thunked" | |
//so it will only be called again when the async action calls it's cb | |
//therefore, the generator is paused at the yield, until `_next` is called by `fs.readFile` or whatever | |
//and therefore the generator object `.next` method is called advancing the | |
//generator so on and so forth until the generator is done `{value: ..., done: true}` | |
cb(_next); | |
} | |
_next(); //start the generator | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment