Personally, when things get messy with dependencies I prefer the following approach:
var externalAccount = Promise.join(payment, t, createExternalAccount),
externalTransaction = Promise.join(externalAccount, payment, t, createExternalTransaction),
address = Promise.join(externalAccount, payment, t, createAddress),
transaction = Promise.join(address, payment, createTransaction),
gatewayTransaction = Promise.join(externalTransaction, transaction, payment, t, createGatewayTransaction);
Makes everything much cleaner, though it's a matter of style.
And if you want to do something after you get gatewayTransaction
's value (asynchronously, of course), you can just:
gatewayTransaction
.then(function (val) {
// do stuff
})
.catch(function (err) {
// do stuff
});
There's one subtle pitfall here that you should be aware of. The order in which the promises are defined is not necessarily the order in which the functions are called. This is what the dependencies look like:
externalAccount -----> externalTransaction -----> gatewayTransaction
|--> address --> transaction --|
Though this is good for performance, you might want to make the whole thing sequential (just like your callback pyramid). In this case, you can write:
var externalAccount = Promise.join(payment, t, createExternalAccount),
externalTransaction = Promise.join(externalAccount, payment, t, createExternalTransaction),
address = Promise.join(externalAccount, payment, t, externalTransaction, createAddress),
transaction = Promise.join(address, payment, createTransaction),
gatewayTransaction = Promise.join(externalTransaction, transaction, payment, t, createGatewayTransaction);
By adding externalTransaction
to address
's dependencies (even though its value isn't needed), you can force it to be sequential.