This article has some examples on avoiding the promise nesting. I’ll copy the relevant parts from the article below:
Often times, one promise will depend on another, but we’ll want the output of both promises. For instance:
getUserByName('nolan').then(function (user) {
return getUserAccountById(user.id);
}).then(function (userAccount) {
// dangit, I need the "user" object too!
});
Wanting to be good JavaScript developers and avoid the pyramid of doom, we might just store the user object in a higher-scoped variable:
var user;
getUserByName('nolan').then(function (result) {
user = result;
return getUserAccountById(user.id);
}).then(function (userAccount) {
// okay, I have both the "user" and the "userAccount"
});
This works, but I personally find it a bit kludgey. My recommended strategy: just let go of your preconceptions and embrace the pyramid:
getUserByName('nolan').then(function (user) {
return getUserAccountById(user.id).then(function (userAccount) {
// okay, I have both the "user" and the "userAccount"
});
});
…at least, temporarily. If the indentation ever becomes an issue, then you can do what JavaScript developers have been doing since time immemorial, and extract the function into a named function:
function onGetUserAndUserAccount(user, userAccount) {
return doSomething(user, userAccount);
}
function onGetUser(user) {
return getUserAccountById(user.id).then(function (userAccount) {
return onGetUserAndUserAccount(user, userAccount);
});
}
getUserByName('nolan')
.then(onGetUser)
.then(function () {
// at this point, doSomething() is done, and we are back to indentation 0
});
As your promise code starts to get more complex, you may find yourself extracting more and more functions into named functions. I find this leads to very aesthetically-pleasing code, which might look like this:
putYourRightFootIn()
.then(putYourRightFootOut)
.then(putYourRightFootIn)
.then(shakeItAllAbout);
That’s what promises are all about.