Что происходит при проверке статуса Promise в JavaScript, если он может выполниться раньше?
Что проверяют
Понимаете ли вы, что у промиса нельзя синхронно спросить статус и что подписка срабатывает всегда асинхронно, даже если результат уже готов. Проверяется модель «состояние плюс подписка», а не представление о флажке, который можно прочитать в любой момент.
Как отвечать
У промиса три состояния: pending, fulfilled, rejected. Переход одноразовый и необратимый, результат фиксируется навсегда, и любой подписчик потом получает именно его.
Синхронно прочитать состояние из кода нельзя: публичного API для этого нет, статус видно только в инструментах разработчика. Отсюда прямой вывод: сценария «проверить статус и на ходу решить, ждать или нет» не существует, есть только подписка через then, catch, finally или await.
Гонки, о которой спрашивают, тоже нет. Если промис успел разрешиться раньше, чем на него подписались, колбэк не выполнится прямо здесь: он встанет в очередь микрозадач и сработает после всего синхронного кода текущей задачи.
const p = Promise.resolve(1);
p.then(() => console.log("then"));
console.log("sync");
// sync, thenПодписываться можно сколько угодно раз и когда угодно, в том числе спустя минуты: готовый промис отдаст сохранённый результат каждому. И отдельно стоит сказать, что функция внутри new Promise выполняется синхронно прямо при создании, асинхронна только доставка результата.
Где спотыкаются
Заводят рядом собственный флаг вроде isDone и ветвятся по нему. Флаг выставляется внутри then, то есть на микрозадачу позже, поэтому проверка сразу после создания всегда видит старое значение. Решение одно: вся логика внутри подписки.
Рассчитывают на синхронный порядок у готового промиса: подписались и тут же читают DOM или переменную, которую колбэк должен был обновить. Порядок обратный, микрозадачи идут после текущего синхронного кода целиком.
Считают, что промис выполняет работу в фоновом потоке. Сам по себе он не выполняет ничего, это обёртка над будущим результатом, а фоновой бывает работа браузера (сеть, таймеры) либо вынесенная в воркер.