Are switches/branches possible in promise chains? Should they be?
See original GitHub issueHello 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:
- Created 10 years ago
- Comments:19 (1 by maintainers)
Top GitHub Comments
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:
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 everyQ
update won’t breakqtree
.E.g. hypothetical code:
Q.when
is still used, but wrapped inqtree.newWhen
: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
androbot
to something more sensible likemcall
mapply
andnmcall
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. 😃