I'm trying to switch from Async.waterfall to Bluebird promises (performance reason, and also because I think promises are more elegant, but that's another discussion).
I have the following code in Async.waterfall:
async.waterfall([
function callGoogle(next) {
request.get(config.google.meEndpoint, {
auth: {bearer: req.body.access_token},
json: true
}, next);
},
function handleGoogleResponse(response, body, next) {
//error handling
next(null, body);
},
function queryDatabase(googleUserInfo, next) {
googleUserModel
//.findOne(...), etc.
.exec(function (err, usr) {
next(err, usr, googleUserInfo);
});
},
function handleUser(googleUser, googleUserInfo, next) {
//googleUser is my internal representation of a user logged in using Google
//googleUserInfo is the information provided by Google
//If googleUser exists, I'm done, otherwise I can use googleUserInfo to create a new googleUser
}], function done());
The problem I'm facing is that using promises, I get something like this:
httpGet(config.google.meEndpoint, {
auth: {bearer: req.body.access_token},
json: true
}).spread(function handleGoogleResponse(response, body){
//error handling
return body;
}).then(function queryDatabase(googleUserInfo){
return googleUserModel
//.findOne(...), etc.
.execAsync();
}).then(function handleUser(googleUser){
//I don't have access to the previous then's googleUserInfo!
});
My queryDatabase function has a nested promise (execAsync
), so the next then
will only get the googleUserModel returned by mongoose.
How can I cascade arguments down a promise chain?