Какое преимущество промисов перед колбэками при работе с асинхронностью в JavaScript
Что проверяют
Понимаете ли вы, что промис это не другой синтаксис колбэка, а объект с гарантиями, которых колбэк не даёт. Про «ад колбэков» интервьюер услышит от каждого, ему интересно, что стоит за этим. Следом обычно спрашивают про микрозадачи и порядок вывода console.log вокруг setTimeout и then.
Как отвечать
Назовите конкретные преимущества:
- значение, а не вызов: промис можно вернуть из функции, сохранить, передать дальше, закэшировать. Колбэк нужно передать заранее, и управление отдаётся чужому коду;
- гарантии исполнения: промис переходит из
pendingвfulfilledилиrejectedодин раз и навсегда. Колбэк чужая библиотека может вызвать дважды, не вызвать вовсе или вызвать то синхронно, то асинхронно; - всегда асинхронно: обработчики
thenзапускаются в очереди микрозадач, даже если промис уже выполнен, поэтому порядок выполнения предсказуем; - композиция:
thenвозвращает новый промис, цепочка остаётся плоской, а вложенность не растёт; - ошибки: исключение внутри
thenпревращается в отклонение и доходит до ближайшегоcatch. В колбэках стиля Node(err, data)ошибку проверяют руками на каждом уровне; - комбинаторы:
Promise.all,allSettled,race,anyдля параллельных запросов; async/await: построен на промисах и позволяет писать обычныйtry/catch.
Честно назовите и ограничения. Промис сам по себе не отменяется, для fetch отмену делают через AbortController. Промис даёт одно значение, для потоков событий остаются колбэки, EventTarget или асинхронные итераторы. Старые API на колбэках оборачивают в промисы, в Node для этого есть util.promisify.
Где спотыкаются
Забывают return внутри then. Цепочка идёт дальше, не дождавшись вложенного запроса, а его ошибка уходит мимо catch.
Оборачивают готовый промис в new Promise(...) без нужды. Код раздувается, а ошибки легко теряются, если забыть вызвать reject.
Думают, что промис выполняет код в другом потоке. Функция-исполнитель в new Promise запускается синхронно, и тяжёлый расчёт внутри промиса блокирует интерфейс так же, как без него.