Promise.resolve() нужен, чтобы получить успешно выполненный промис. Метод вызывается у Promise, принимает значение и возвращает промис, который будет завершён успешно с этим значением или перейдёт в состояние переданного thenable-объекта.
Синтаксис
Базовая запись выглядит так:
Promise.resolve()
Или так:
Promise.resolve(value)
Где:
value- значение, промис или thenable-объект, который нужно преобразовать вPromise
Что возвращает Promise.resolve()
Метод всегда возвращает объект Promise.
const promise = Promise.resolve(5);
console.log(promise instanceof Promise); // true
promise.then((value) => {
console.log(value); // 5
});
Если передано обычное значение, вы получите успешно выполненный промис с этим значением.
Простой пример
Promise.resolve("Готово").then((value) => {
console.log(value); // "Готово"
});
Это короткий способ создать промис, который уже считается успешно завершённым.
Без аргументов Promise.resolve() возвращает промис с undefined
Это полезно помнить.
Promise.resolve().then((value) => {
console.log(value); // undefined
});
Такой вызов создаёт успешно выполненный промис без явного результата.
Promise.resolve() удобно оборачивает обычное значение в промис
Это один из самых частых сценариев.
const user = { id: 1, name: "Анна" };
Promise.resolve(user).then((value) => {
console.log(value.name); // "Анна"
});
Это удобно, когда код дальше ожидает именно Promise, даже если на текущем шаге значение уже готово.
Обработчики всё равно запускаются не синхронно
Здесь легко ошибиться.
Хотя промис из Promise.resolve() уже успешно завершён, then() всё равно выполнится не посреди текущего синхронного кода, а позже.
console.log("start");
Promise.resolve(5).then((value) => {
console.log(value); // 5
});
console.log("end");
Результат будет таким:
start
end
5
Поэтому Promise.resolve() не делает код синхронным.
Если передать уже готовый промис, метод может вернуть его же
Это важный практический нюанс.
const promise = Promise.resolve(5);
console.log(Promise.resolve(promise) === promise); // true
Если в Promise.resolve() передать обычный промис Promise, дополнительная обёртка обычно не создаётся.
Если передать thenable-объект, Promise.resolve() подстроится под него
Thenable - это объект с методом then, который ведёт себя похоже на промис.
const thenable = {
then(resolve) {
resolve(42);
},
};
Promise.resolve(thenable).then((value) => {
console.log(value); // 42
});
Promise.resolve() не просто кладёт такой объект внутрь результата, а пытается принять его состояние.
Если у thenable возникает ошибка, получится отклонённый промис
Это тоже полезно знать.
const thenable = {
get then() {
throw new Error("boom");
},
};
Promise.resolve(thenable).catch((error) => {
console.log(error.message); // "boom"
});
В таком случае метод вернёт уже не успешный, а отклонённый промис.
Promise.resolve() не копирует объекты
Метод только оборачивает значение в промис, но не клонирует его.
const user = { name: "Анна" };
Promise.resolve(user).then((value) => {
value.name = "Иван";
console.log(user.name); // "Иван"
});
Если нужен независимый объект, его надо копировать отдельно.
Чем Promise.resolve() отличается от new Promise(...)
Оба варианта могут привести к успешному промису, но Promise.resolve() обычно проще и короче.
const promise1 = Promise.resolve(5);
const promise2 = new Promise((resolve) => {
resolve(5);
});
Если нужно просто получить успешно выполненный промис из уже известного значения, Promise.resolve() обычно удобнее.
new Promise(...) чаще нужен, когда вы вручную описываете асинхронную операцию.
Когда это полезно
Promise.resolve() особенно удобен, когда:
- нужно быстро вернуть успешный промис
- функция иногда отдаёт обычное значение, а иногда промис, и вы хотите привести всё к одному формату
- нужно начать promise-цепочку с готового значения
- вы пишете API, которое всегда должно возвращать
Promise
Пример:
function getUserName(fromCache) {
if (fromCache) {
return Promise.resolve("Анна");
}
return fetch("/api/user")
.then((response) => response.json())
.then((user) => user.name);
}
Такой подход помогает сделать возвращаемый формат единым.
Частые ошибки
Думать, что Promise.resolve() возвращает сразу само значение
const result = Promise.resolve(5);
console.log(result); // Promise
Результат метода - это не число 5, а промис.
Ожидать синхронное выполнение then()
console.log("A");
Promise.resolve("ok").then((value) => {
console.log(value);
});
console.log("B");
Сначала выведется A, потом B, и только потом ok.
Думать, что Promise.resolve() ловит синхронные ошибки в аргументе
Promise.resolve(JSON.parse("{"))
.catch((error) => {
console.log(error);
});
Здесь JSON.parse("{") выбросит ошибку ещё до вызова Promise.resolve(). Значит, такой catch() не поможет.
Считать, что Promise.resolve() копирует объект
const user = { name: "Анна" };
Promise.resolve(user).then((value) => {
value.name = "Иван";
});
Внутри промиса остаётся тот же самый объект.
Оборачивать в Promise.resolve() то, что уже и так возвращает промис, без необходимости
Promise.resolve(fetch("/api/user"));
Такой код обычно лишний, потому что fetch() уже возвращает промис.
Быстрая памятка
Promise.resolve()вызывается уPromise- метод всегда возвращает объект
Promise - без аргументов результатом будет промис с
undefined - обычное значение превращается в успешно выполненный промис
- уже готовый промис
Promiseможет быть возвращён как есть - thenable-объект будет обработан как источник состояния
- обработчики
then()всё равно запускаются асинхронно - метод не копирует объекты
Promise.resolve()удобен для унификации возврата вPromise
Коротко
Promise.resolve() в JavaScript нужен, чтобы быстро получить успешно выполненный промис из значения, thenable-объекта или уже существующего промиса. Главное, что стоит запомнить: метод всегда возвращает Promise, не делает код синхронным, не копирует объекты и особенно полезен там, где нужно привести разные варианты результата к единому promise-формату.