Hacker News new | past | comments | ask | show | jobs | submit login

Cool trick with the redundant indentation which can be applied to generators too:

    #Without generators
    Credentials.get({ token })
        .then(credentials => User.get({ username: credentials.username }))

    #With generators

    var credentials = 
        yield Credentials.get({ token })
            User.get({ username: credentials.username })



This might be not a very good example. But generators have more good features than just cleaner code.

1. You write code almost like synchronous one. You can use any control-flow statements you are familiar with. Just dont forget to turn a promise into real value with `yield` keyword.

2. How much times have you wrote such statements?

    X.prototype.foo = function() {
        var self = this;
        // or
        var that = this;
        this.bar().then(function(x) {
            that.baz(x);
        });
    };
or }.bind(this));

With yield you can just write your logic, not a boilerplate:

    X.prototype.foo = async(function*() {
        var x = yield this.bar();
        this.baz();
    });


1. Yes this is the problem. It is very easy to write something like this:

    var a = yield A();
    var b = yield B();
This is massively less performant than:

    var a = A();
    var b = B();
    a = yield a;
    b = yield b;
In promises you naturally do `Promise.all([A(), B()]).spread((a, b) => //Use a and b);`

2. Why did you stop using arrow functions?

    X.prototype.foo = function() {
        this.bar().then(x => this.baz(x));
    };
3. You are overvaluing control-flow constructs. Try-catch is always a catch-all error silencer where as promises can extend `.catch()` and `.finally()` to overcome flaws. Hand written loops are not that common, one mostly uses .filter, .map and .reduce in these kind of work flows.


1. You can easily write the same crappy code with promises anyway. And if you do think that `Promise.all` will save you, then you can use it with yield. With destructuring you even don’t need `.spread`.

Even more, with yield you can easily achieve parallel execution just moving `yield` keyword to the place where you need actual value. Good luck doing this with promises.

2. Unfortunately, traceur-compiler does not support fat arrow yet;

3. If you use try-catch just as a silencer, man I have bad news for you. And if you provide real error-handling in `.fail()` then what’s the problem writing the same code inside catch clause?


Well yes you can achieve better concurrent execution if you essentially duplicate the code. I also showed you how to do it with promises already (in 1 line) so not sure why you are wishing me good luck :)

There is just no way to use yield without it either being superfluous or sacrificing concurrency. Of course it is great when you have a sequence I guess, but promise code with arrows is not messy in comparison, maybe slightly more verbose at best.

Consider something like this which is far from optimal:

    let suspend = require('suspend'),
        request = require('request');

    let getParsed = suspend(function* (urls) {
        urls.forEach((url) => request(url, suspend.fork()));
        return (yield suspend.join()).map((r) => parseBody(r.body));
    });
This is again very easy to write inadvertently.

Maximizing concurrency:

    let getParsed = Promise.coroutine(function* (urls) {
        return yield urls.map((url) => {
            request(url).spread((response, body) => parseBody(body));
        });
    });
However, now that we have maximum concurrency, it is entirely pointless to even have a generator:

    let getParsed = urls =>
        urls.map((url) => {
            request(url).spread((response, body) => parseBody(body));
        });
    });
I said try-catch silences all errors that are not event meant to be handled but are bugs in code that should never be thrown in the first place. For example, if you have a typo in your code you will not know about that instead you will handle it like an expected error like network error.

Since promise `.catch()` is not limited by the language, you can do e.g. `.catch(NetworkError, e => ());` or whatever.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: