3

Does anybody have any thoughts about ES6 promises, I'm using them in my Node app and I love them, on the most part. But Ive found that if I get some sort of error in a resolve callback, it won't throw an error or execute the reject callback, and its leaving me with my server hanging infinitely.

For now I've resorted to doing this, and manually rejecting the promise with the caught error, but I'm not sure if this a great way to handle, and/or if I should be using promises at all.

this.dataStore.set(newID, value).then( (foo) => {
    try{
        this.var = foo;
        res({val: foo});
    }catch(e){
        rej(e);
    }
}, (e) => {
    rej(e);
});
user3240114
  • 123
  • 1
  • 10
  • Does your code work correctly as-is, and you're simply looking for a *better* solution? – apsillers May 11 '15 at 11:27
  • 1
    Where do `res` and `rej` come from? This looks a lot like the [`Promise` constructor antipattern](http://stackoverflow.com/q/23803743/1048572) – Bergi May 11 '15 at 12:41
  • This also looks a bit like the http://petkaantonov.github.io/bluebird/web/docs/anti-patterns.html#the-.then – Benjamin Gruenbaum May 11 '15 at 13:21

1 Answers1

4

I think the confusion is arising from the fact that, based on your use of res, and rej here, you are likely calling this from within a promise constructor, along the lines of

function setStore(newID, value) {
    return new Promise(function(res, rej) {
        this.dataStore.set(newID, value).then( (foo) => {
            try{
                this.var = foo;
                res({val: foo});
            }catch(e){
                rej(e);
            }
        }, (e) => {
            rej(e);
        });
    });
}

By the way, the (e) => { rej(e); } part at the end could be rewritten as e => rej(e), which in turn could be rewritten as rej.

But anyway, you don't need any of that surrounding machinery to create and return your own promise, because this.dataStore.set and/or the ensuing call to then already creates a promise, which you can return as is. Instead of creating your own new promise, and then resolving your new promise with the little hash based on the result passed to then, just return the hash--that will become the value of the resulting promise. Instead of rejecting your new promise when the call to dataStore.set fails, just let the failed promise be itself.

So you shouldn't need to do anything more complicated than

function setStore(newID, value) {
    return this.dataStore.set(newID, value).then(foo => {
        this.var = foo;
        return {val: foo};
    });
}

An error occurring in the this.var = foo; return {val: foo}; part (but how could it?) will automatically throw the promise into failure state. A failure resulting from this.dataStore.set will yield a failed promise as is, and there is no need to catch it and rethrow it--the failure will progress merrily down the chain.

Use this as:

setStore('abc', 123) 
    .then(hash => console.log(hash.val))
    .catch(e => console.log("The sky is falling", e));

As a matter of clarification, in the following:

promise.then(success, failure)

an error arising in the success callback is not handled in the failure callback. A failure in the success callback would be handled in successive stages of the chain. You could handle a failure in success (or promise itself) with

promise.then(success).catch(failure)
HyderA
  • 20,651
  • 42
  • 112
  • 180