Skip to content

Instantly share code, notes, and snippets.

@datchley
Created February 24, 2016 15:09
Show Gist options
  • Select an option

  • Save datchley/e6701254dbb66025d476 to your computer and use it in GitHub Desktop.

Select an option

Save datchley/e6701254dbb66025d476 to your computer and use it in GitHub Desktop.

Revisions

  1. @vatchley vatchley created this gist Feb 24, 2016.
    71 changes: 71 additions & 0 deletions async-generator-runner.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,71 @@
    // 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);