In general for getting rid of this waterfall effect, you can change something like this:
asyncService.doSomething()
.then(function(res) {
asyncService.doSomethingElse(res)
.then(function(secondRes) {
asyncService.doAThirdThing(secondRes)
.then(function(thirdRes) {
// continue
});
});
});
to this:
asyncService.doSomething()
.then(function(res) {
return res;
})
.then(function(res) {
return asyncService.doSomethingElse(res);
})
.then(function(secondRes) {
return asyncService.doAThirdThing(secondRes);
})
.then(function(thirdRes) {
// etc.
});
This solution works because Promise methods return promises themselves.
This is a just an syntactic implementation detail, but the code does the same thing.
If you're using ES6 along with CoffeeScript, try using a library like co to leverage synchronous-looking async code (by using generators).
You can also use something like promise-waterfall, or see if there are any backfill libraries available for the upcoming ES7 async/await.
edit
To handle Promise.each
:
.then(function() {
return Promise.each(/* do stuff */);
})
.then(function(result) {
// do stuff
});