question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Are switches/branches possible in promise chains? Should they be?

See original GitHub issue

Hello clever people,

Is there, or should there be, a way to switch chains (or ‘branches’) for a promise?

Code is so very pretty when you have your promise chain separate from your functions, e.g.

getPromise()
.then(someFunc)
.then(someFoo)
.then(someBar)
// ...
.done();

It’s almost as gratifying as separating layout from content. But I find myself having functions that become if statements to include different promise chains, e.g.

someBaz(val) {
    var promise = q.fcall(trySomething, val) // trySomething will return a promise or purposely throw error if it knows it can't make any promises
    .fail(
        function (err) {
            if (err.message == 'This was to be expected.')
                return someBazBazBaz(val); // Try alternative function to return the promise

            // If this was not the expected error, then it must be a serious error.
            throw err;
        }
    );

    return promise;
}

However, this is purely chain switching, so it would be nice if we could keep that in the chain part, without using so much code that will prevent the promise chain from looking sexy.

Do you know some trickery to make this short and nice to make this fit in the chain? Should there be a switching function? E.g.:

getPromise()
.then(someFunc)
.then(someFoo)
.if(compareFunction, 
    function(promise){ // value is already promise in this chain, making code shorter
        // true
        return promise
        .then(bakeCookies);
    }, 
    function(promise){
        // false
        return promise
        .then(buyCookies);
    }
)
.then(someCookieFun) // continues with whichever branch was followed above
// ...
.done(someBaz)

Maybe it can be even shorter. I’ve seen some nifty tricks.

PS - I am not sure if I asked something like this before, or if I was just playing with the thought. I cannot find it back, so it was probably in my head.

Issue Analytics

  • State:closed
  • Created 10 years ago
  • Comments:19 (1 by maintainers)

github_iconTop GitHub Comments

1reaction
Redsandrocommented, Jun 13, 2013

I am trying to make promises aware of their switched state, so I can have daisychained conditionals.

Is it clever to extend Q internal functions (e.g. when()) with a wrapper function by overriding the prototype (e.g. then())? Or is there a better (smarter) way to do this?

(you can skip the rest, just some examples to show what I mean)


E.g. In order to do branch-aware promises:

getPromise()
.case('someValue')
    .then(someBazBaz) // No break, continues with next case
.case('otherValue')
    .then(someBarBar)
    .break() // Break, skips to esac()
.default() // When no case is matched
    .then(someFooBaz)
.esac() // Promise no longer needs to be branch-aware.

I need to add a ‘secret’ property to promises to notify them to skip then()s under certain conditions, but I want to be as non-invasive as possible so every Q update won’t break qtree.

E.g. hypothetical code: Q.when is still used, but wrapped in qtree.newWhen:

q.makePromise.prototype.then = function (fulfilled, rejected, progressed) {
    return newWhen(this, fulfilled, rejected, progressed);
};

newWhen = function(promise, fulfilled, rejected, progressed) {
    if (promise.secretProperty) // some wizardry TBD
        return promise; // Ignore this then()
    else
        return q.when(promise, fulfilled, rejected, progressed);
1reaction
Redsandrocommented, Jun 3, 2013

No, I was raised atheist and was told not to listen to what churches write. So I never really took a look at the inventions of Alonzo Church.

J/k, never heard about Lambda Calculus combinators. I got to know anonymous functions as Lambda-style functions (in PHP) and that’s it. Thanks for the explanation.

I understand you disagree and you’re probably right. In my personal opinion, having a complete solution adds so much value to a module, and I would not consider something bloat if it adds many possibilities (promise trees in stead of promise chains) with just a handful of code. I remember some other module that decided to include prototype.js one day. Adding ~170K for some functionality, that would be bloat in my book.

Just my POV, I am perfectly happy adding it manually. 😃

Btw, if non-bloat, plain, slim and clean is really paramount, I still suggest changing core functions like post, tickle and robot to something more sensible like mcall mapply and nmcall as I suggested here: https://github.com/kriskowal/q/pull/235 Because I have to look them up in the documentation all the time.

2 cents. 😃

Read more comments on GitHub >

github_iconTop Results From Across the Web

Chaining Javascript promises - Stack Overflow
First, a little background on how the relevant parts of promises work: p1.then(...) does return a new promise that is chained to the ......
Read more >
JavaScript Promise Tutorial: Resolve, Reject, and Chaining in ...
When we define a promise in JavaScript, it will be resolved when the time comes, or it will get rejected. Promises in JavaScript....
Read more >
Using Javascript Promises to chain asynchronous actions in ...
On the Promise branch, the sequence is very clear: We append, then we append some more, then we append some more, then we...
Read more >
Please don't nest promises - DEV Community ‍ ‍
One can solve the issue of nested promises by remembering that the return value of the callback function will always be wrapped in...
Read more >
Handling exceptions thrown in promises - ReScript Forum
inside of a promise callback would be any less type safe than using it outside of a promise. Branch B in the switch...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found