Closed cyberwombat closed 11 years ago
Here you go:
// Looks a lot like plain old functional composition:
// call Async1 first, then pass it's result as a param when calling Async 2:
var promiseForResultOfAsync2 = nodefn.call(Async2, nodefn.call(Async1));
If you need to call done at the end, no matter what, regardless of success or error and don't care about result
, as your example shows, you can use ensure
. (FYI, typically a function like done
that you use to signal the end of an async operation simply isn't needed with promises, but it depends on the situation, of course).
nodefn.call(Async2, nodefn.call(Async1)).ensure(done);
It all gets even better if you use lift
to create promise-aware functions from node-style functions:
var pAsync1 = nodefn.lift(Async1);
var pAsync2 = nodefn.lift(Async2);
// Now it all looks like regular function calls
var promiseForResultOfAsync2 = pAsync2(pAsync1());
// Or, if you need done()
pAsync2(pAsync1()).ensure(done);
This is one of the great things about promises ... they take the nested continuation passing style of asynchrony, and give you back regular call-and-return style programming. Only at the point of needing to observe the ultimate result of a computation do you need to use .then()
or .ensure()
, etc.
EDIT: Fixed use of pAsync[1,2]
Fantastic - I really appreciate you taking the time!
If I wanted to do something with "res" before I pass it to Async2, what would be the approach? Say I needed to pass res.something
Lots of options :) Here's a few that are equivalent:
function getSomething(res) { return res.something; }
// Given the lifted pAsync1 and pAsync2 from above
var promiseForResult = pAsync1().then(getSomething).then(pAsync2);
// Equivalent, but imho, less intuitive
var promiseForResult = pAsync2(pAsync1().then(getSomething));
Of course, you can lift getSomething as well, so that it can accept a promise as a arg!
var fn = require('when/function');
var getSomething = fn.lift(function(res) { return res.something; }); // getSomething can accept a promise for its arg
// Now they all compose
var promiseForResult = pAsync2(getSomething(pAsync1()));
Depends on the situation as to whether you want/need to take it that far, of course. Good to have options tho :)
Super helpful. I think I am making promises more complicated than I need to. This makes total sense.
No worries :) Promises can take a while to get your head around, for sure. Once you do, though, you're right, they can make things much simpler. Please also feel free to ask promise-related questions in the cujoJS google group, or in #cujojs on freenode IRC.
Having a little trouble figuring out the proper way to do this using When:
I've got
var a1 = nodefn.call(Async1);
but not sure how to get 'res' from there?