Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@datchley
Created February 24, 2016 15:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save datchley/e6701254dbb66025d476 to your computer and use it in GitHub Desktop.
Save datchley/e6701254dbb66025d476 to your computer and use it in GitHub Desktop.
A runner for creating async generators for various types of sources
// Sources...
let arr = [1,2,3,4];
// thunk returning function that takes a callback
// and applies the arg to it after ms milliseconds timeout
function delay(arg, ms=1000) {
return function(callback) {
setTimeout(_=>callback(arg), ms);
};
}
// Array generator, async using Promises
function* promiseGenerator(source, ms=1000) {
for (let val of source) {
yield new Promise((resolve, reject)=>{
setTimeout(_=>resolve(val), ms);
});
}
}
// Array generator, async using callbacks
function* callbackGenerator(source, ms=1000) {
for (let val of source) {
yield delay(val);
}
}
// Array generator, synchronous
function* arrayGenerator(source) {
for (let val of source) {
yield val;
}
}
// Generator runner that can handle generators that return
// 1. values (synchronous)
// 2. Promises (asynchronous)
// 3. Callbacks (asynchronous)
function run(gen) {
var it = "next" in gen ? gen : gen(),
ret;
// asynchronously iterate over generator
(function iterate(val){
ret = it.next( val );
console.log(val);
if (!ret.done) {
// poor man's "is it a promise?" test
if (typeof ret.value == 'object' && 'then' in ret.value) {
// wait on the promise
ret.value.then( iterate );
}
else if (typeof ret.value == 'function') {
ret.value(iterate);
}
// immediate value: just send right back in
else {
// avoid synchronous recursion
setTimeout( function(){
iterate( ret.value );
}, 0 );
}
}
})();
}
let it = promiseGenerator(arr);
let it2 = callbackGenerator(arr);
run(it);
run(it2);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment