Частый случается когда нужно послать несколько запросов в API каждый из которых зависит от результата выполнения предыдущего.

Рассмотрим пример на angular.js. Пример как это делать с помощью келлбеков или как это делают люди, которые не научились работать с промизами:

myService.check(params1).then(function (result) {
    if (result) {
        myService.check(params2).then(function (result) {
            if (result) {
                myService.check(params3).then(function (result) {
                    console.log('done');
                });
            }
        });
    }
});

Получили pyramid of doom. Писать и тем более читать такой код очень не удобно. И здесь еще нет обработки ошибок. Как раз чтобы не городить вложенные келлбеки и нужны промизы.

Перепишем этот пример правильно:

myService.check(params1).then(function (result) {
    if (result) {
        return myService.check(params2);
    }
})
.then(function (result) {
    if (result) {
        return myService.check(params3);
    }
})
.then(function (result) {
    console.log('done');
})
.catch(function (error) {
    console.log(error);
});

Не меняя функционала мы получили более плоскую структуру кода которую проще читать и поддерживать. Кроме того добавился обработчик ошибок, который вызовется если ошибка произойдет во время любого из этих запросов.

Но иногда возникают ситуации когда таких последовательных запросов может быть очень много, тогда получится большая портянка однообразного кода. Перепишем предыдущий пример свернув общую часть:

var params = [params1, params2, params3];
var t = $q.resolve();

params.forEach(function (param) {
    t = t.then(function () {
        return myService.check(param);
    });
});
t.then(function () {
    console.log('done');
})
.catch(function (error) {
    console.log(error);
});