The simplest option to have access to both customer
and processingResult
without nesting would probably be to use async/await
(ES7 feature) like this (this would need to be inside an async
function declaration):
async function someFunction() {
const customer = await GetCustomer();
const processingResult = await ProcessCustomer(customer);
console.log(customer);
console.log(processingResult);
return someValue;
}
// usage
someFunction().then(result => {
// done here
}).catch(err => {
console.log(err);
});
What are the disadvantages of the first approach,
At just two levels like this, there are no particular disadvantages to nesting. You MUST return the inner promise in order to be able to get final result and full error handling. So, to use the first option properly with nesting, you would need to at least return the inner promise so you can catch all errors at the top level:
GetCustomer().then(customer => {
return ProcessCustomer(customer).then(processingResult => {
console.log(customer);
console.log(processingResult);
return someValue;
});
}).catch(err => {
// catch all errors here
console.log(err);
});
If you get more levels, the nesting gets less and less readable.
and/or the advantages of the second?
It's really just personal opinion at this point. I'm personally not a fan of passing a raw value to Promise.all()
just so it will pass it through to a common .then()
handler. It appears to make the code more complicated looking than it actually is (but that's just my opinion). It would work just fine.
This is a place where object destructing would make things a little more readable and you need a .catch()
handler:
GetCustomer().then(customer => {
return Promise.all([customer, ProcessCustomer(customer)]);
}).then(([customer, processedCustomer]) => {
console.log(customer);
console.log(processedCustomer);
}).catch(err => {
console.log(err);
});
For a number of other options, see here:
How to Chain and Share Prior Results With Promises
Promise.all()
in that situation? There's only one async operation - no need forPromise.all()
.customer
was created. Where "chaining" approach will need to look only one step back.customer
is used alongsideprocessingResult
. You don't hold onto it if you justGetCustomer().then(ProcessCustomer).then(processingResult => ... )