Generator Async Runner. Makes it possible to yield and wait for callbacks and thunks.
Generator Async Runner. Makes it possible to yield and wait for callbacks and continuables.
Supports both async functions that use node-style callbacks and continuable-returning async functions.
A "continuable" is simply a function that accepts a node style callback as it's only argument.
A simple example is turning the
setTimeout function to return a continuable instead of accepting a callback.
Here is an example using ES6 generators with the
gen-run library to implement sleep.
var run = require'gen-run';runconsole.log"Hello";yield sleep1000;console.log"World";;
If you pass a second parameter to
run() it will call the function back with the return result of the function. For example,
runconsole.log"Hello";yield sleep1000;console.log"World";return "Hello World";if err console.log"Error encountered: " + err;else console.logvalue;;
Since this works by yielding continuables to the run function, delegating yield will also just work.
while nconsole.logn--;yield sleep10;runconsole.log"Start";yield* sub10;console.log"End";;
The runner is aware that sometimes callbacks may be called before the continuable function returns and has safeguards internally to prevent stack overflows.
returncallbacknull n - 1;;runvar i = 100000;while ii = yield decrementi;;
There is also protection from evil functions that may call the callback multiple times when they should only ever call it once. Run will simply ignore subsequent calls from the same continuable.
returncallbacknull 1;setTimeoutcallbacknull 2;100;runconsole.log"Hello";yield evil;yield sleep1000;console.log"World";;
I assume the callback in the continuable will be of the form
(err, item) and will return the item as the result of yield or throw
err into the generator. This means that you can use async functions as if they were normal sync functions.
// Wrap fs.readFile as a continuable style function.// Also intercept ENOENT errors and instead return for the resultreturnfsreadFilepath encodingif errif errcode === "ENOENT" return callback;return callbackerr;return callbacknull data;;;runtryvar contents = yield readFile"/myfile.txt" "utf8";if contents// the file existed and was not emptycatch err// There was a problem reading the file, but it did exist.;
Gen-Run has basic built-in support for parallel work via yielding arrays or maps of continuables.
If you yield an array of continuable functions, it will run them all in parallel and return the results. If there is an error in any of them, the expression will throw.
The same works for objects except the result is an object. This allows for named data.
That's OK. In node.js land, you can require your users or your app's deployment to use a certain version of node.js that has generators. But for browsers and older versions of node there are transpilers. https://github.com/google/traceur-compiler, for example can convert ES6 generator code to vanilla ES5 code.
No, gen-run also works with any callback based API using a slightly more explicit syntax.
runconsole.log"Hello";yield setTimeoutgen 1000;console.log"World";;
This alternate API can be mixed and matched with continuable style APIs. If you yield a function, it will assume it's a continuable and pass in a callback. If you don't, it's your responsibility to pass in the generated callback manually in the right place.
If you want to use delegate yield with the explicit style it's up to you to pass the
gen function to the child generator.
while nconsole.logn--;yield setTimeoutgen 10;runconsole.log"Start";yield* subgen 10;console.log"End";;
This library is the result of my lua research and researching many other similair libraries and taking the parts I like from them. Libraries I took inspiration from are:
The MIT License (MIT)
Copyright (c) 2013 Tim Caswell
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.