javascriptnode.jsbabeljscoecmascript-2017

Difference between co and await


I'm not really understanding the difference between this code:

co(function *() {
    const val = yield aPromise();
    return val;
})
.then((val) => doSomethingWith(val), (err) => doSomethingWith(err));

and this other one:

async function () {
    try {
        const val = await aPromise();
        doSomethingWith(val);
    } catch (err) {
        doSomethingWith(err);
    }
}

What are the pros/cons (in terms of performance, readability and flow control mainly) of each code used in a browser or in server (node.js) and why should co (which depends on co external library) or await (which is not part of ES7 yet and depends on babel-polyfill) be used.


Solution

  • Two major differences for the example code you've shown:

    Now, I think what you actually wanted to compare are

    var example = co.wrap(function *() {
        try {
            const val = yield aPromise();
            doSomethingWith(val);
        } catch (err) {
            doSomethingWith(err);
        }
    })
    

    and

    async function example() {
        try {
            const val = await aPromise();
            doSomethingWith(val);
        } catch (err) {
            doSomethingWith(err);
        }
    }
    

    and possibly

    function example() {
        return aPromise().then(doSomethingWith).catch(doSomethingWith);
    }
    

    (the last one actually has a different behaviour if aPromise throws synchronously, which it of course should never do)

    So lets discuss

    performance

    Does not matter. Really not. Although the third one might be the fastest because it creates the least amount of promises, and the other two are not yet optimised well in engines.

    readability

    Choose yourself. The first two are pretty much equivalent, though co is a bit ugly (abusing generator syntax). The third is pretty concise and could be favoured because of that, although this advantage is quickly lost for everything with complex control flow.

    flow control

    That's not a question of pros/cons, it has to be the one you want.

    why should co or await be used?

    co should not be used any more, it's superseded by the standard ES8 (ES2017) async/await (which is not yet published, but still). It might still be used as a transpiler target (for environments that support ES6 but not ES8) or for backwards-compatibility when it was used with something else than promises (given that co supports more types of "yieldables").