Wrapper to hide all generator switching machinery

by Olegas

HTML

<div id="log"></div>

JavaScript

asyncWrap(function *() {

    var currentTime;
    
    log('Lets wait 5 sec');
    
    currentTime = yield promiseFromTimer(5000);
    
    log('Current time is ' + currentTime + '. Now lets wait 10 sec');
    
    try {
        currentTime = yield exceptionFromTimer(10000);
        // Will never happen
        log('Current time is ' + currentTime + '. Ok then, lets stop');
    } catch(e) {
        log('Got exception: ' + e + ' at ' + (new Date()));
    }
    
    var fourtytwo = yield plusTwo(40);
    
    log('And... the meaning of life is ' + fourtytwo);
    
});

function asyncWrap(g) {

    function step(v) {
        var val = (v instanceof Error ? it.throw(v) : it.next(v));
        if (val.done) {
            return;
        }
        val = val.value;
        if (val instanceof Promise) {
            val.then(step, step);
        } else {
           step(val);
        }
    }

    var it = g();
    step();
}

function plusTwo(n) {
    return n + 2;
}

function promiseFromTimer(delay) {
    return new Promise(function(fulfil) {
        setTimeout(fulfil.bind(null, new Date()) , delay);
    });
}

function exceptionFromTimer(delay) {
    return new Promise(function(fulfil, reject) {
        setTimeout(reject.bind(null, new Error('Oh!')), delay);
    });
}

function log(s) {
    var p = document.createElement('p');
    p.appendChild(document.createTextNode(s));
    document.getElementById('log').appendChild(p);
}