# Проблема promise hell в JavaScript

Вы уже знаете, что промисы были созданы для того, чтобы решить проблему callback hell. Однако, со временем оказалось, что промисы также способны породить сложный код. Эта проблема по аналогии была названа promise hell.

Давайте рассмотрим эту проблему на примерах кода. Пусть у нас есть функция `getSmth`, получающая параметр и возвращающая результат в зависимости от этого параметра:

`function getSmth(num) { return new Promise((resolve, reject) => { setTimeout(() => resolve(num * num), 1000) }); }`

В данном случае мы имитируем некоторую полезную операцию (например, получения данных с сервера). В качестве имитации мы просто параметром передаем число и через секунду возвращаем квадрат этого числа.

Давайте теперь воспользуемся нашей функцией `getSmth` внутри другой функции:

`function func() { getSmth(2).then(res => { console.log(res); // выведет 4 }); } func();`

## Первая проблема

Множество следующих друг за другом конструкций `then` затрудняют понимание кода:

`function func(){ getSmth(2).then(res1 => { // делаем что-то }).then(res2 => { // делаем что-то }).then(res3 => { // делаем что-то }).then(res4 => { // делаем что-то }).then(res5 => { // делаем что-то }).then(res6 => { // делаем что-то }); } func();`

## Вторая проблема

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

`function func() { getSmth(2).then(res1 => { getSmth(3).then(res2 => { console.log(res1 + res2); // выведет 13 }); }); } func();`

Уже напоминает callback hell, не так ли? Добавим еще один вызов функции - код станет еще хуже:

`function func() { getSmth(2).then(res1 => { getSmth(3).then(res2 => { getSmth(4).then(res3 => { console.log(res1 + res2 + res3); }); }); }); } func();`

Можно, конечно же, воспользоваться `Promise.all`:

`function func() { Promise.all([getSmth(2), getSmth(3), getSmth(4)]).then(res => { console.log(res[0] + res[1] + res[2]); }); } func();`

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

`function func() { getSmth(2).then(res1 => { getSmth(res1).then(res2 => { getSmth(res2).then(res3 => { console.log(res3); }); }); }); } func();`
←→
↑
en ru