Promise.then: примеры (JAVASCRIPT)
Promise.then(onFulfilled (function), onRejected (function)): PromiseБазовое описание метода
Метод then() является частью объекта Promise в JavaScript. Он используется для обработки результатов выполнения асинхронных операций после их завершения.
Метод вызывается, когда промис переходит в состояние fulfilled (успешно выполнен) или rejected (выполнен с ошибкой).
Аргументы метода
onFulfilled (необязательный) - функция, которая вызывается при успешном выполнении промиса. Принимает один аргумент - результат выполнения промиса.
onRejected (необязательный) - функция, которая вызывается при отклонении промиса. Принимает один аргумент - причину отклонения (ошибку).
Возвращаемое значение
Метод возвращает новый объект Promise, что позволяет создавать цепочки вызовов. Возвращаемый промис разрешается со значением, которое вернула вызванная функция-обработчик.
Простые примеры использования
Пример с обработкой успешного выполнения:
const promise = new Promise((resolve) => {
setTimeout(() => resolve('Данные получены'), 1000);
});
promise.then(
(result) => {
console.log(result);
return result + ' и обработаны';
}
).then(result => console.log(result));Данные получены Данные получены и обработаны
Пример с обработкой ошибки:
const failingPromise = new Promise((resolve, reject) => {
setTimeout(() => reject(new Error('Ошибка загрузки')), 1000);
});
failingPromise.then(
result => console.log('Успех:', result),
error => console.log('Ошибка перехвачена:', error.message)
);Ошибка перехвачена: Ошибка загрузки
Пример с одним обработчиком:
Promise.resolve(42)
.then(value => value * 2)
.then(value => console.log('Результат:', value));Результат: 84
Похожие методы в JavaScript
Promise.catch() - специализированный метод для обработки ошибок. Рекомендуется использовать вместо второго аргумента then для улучшения читаемости кода.
promise
.then(result => process(result))
.catch(error => handleError(error));Promise.finally() - выполняется независимо от результата промиса. Полезен для очистки ресурсов.
Async/await - синтаксический сахар над промисами, позволяющий писать асинхронный код в синхронном стиле. Используется для упрощения сложных цепочек then.
Аналоги в других языках программирования
Python (asyncio):
import asyncio
async def main():
result = await some_async_function()
print(result)
asyncio.run(main())PHP (Promises для Guzzle):
$promise = $client->requestAsync('GET', 'https://example.com');
$promise->then(
function ($response) {
echo $response->getStatusCode();
}
);C# (Task.ContinueWith):
Task.Run(() => SomeWork())
.ContinueWith(task => {
Console.WriteLine(task.Result);
});Kotlin (Coroutines):
GlobalScope.launch {
val result = async { fetchData() }.await()
println(result)
}Типичные ошибки
Забытый возврат значения из обработчика:
Promise.resolve(5)
.then(value => {
value * 2; // Ошибка: нет return
})
.then(result => console.log(result)); // undefinedundefined
Необработанные ошибки в цепочке:
Promise.reject(new Error('Ошибка'))
.then(result => console.log(result))
.then(() => console.log('Этот код не выполнится'));Использование then для уже завершенного промиса:
const promise = Promise.resolve('данные');
setTimeout(() => {
promise.then(result => console.log(result)); // Сработает
}, 1000);Изменения в последних версиях
В современных версиях JavaScript метод then не претерпел существенных изменений. Основные улучшения связаны с интеграцией с async/await синтаксисом.
В ES2022 улучшена трассировка стека для асинхронных операций, что упрощает отладку цепочек then.
Спецификация продолжает гарантировать микротасковую очередь для обратных вызовов then, обеспечивая детерминированный порядок выполнения.
Расширенные примеры
Параллельная обработка нескольких промисов:
const fetchUser = fetch('/api/user');
const fetchPosts = fetch('/api/posts');
Promise.all([fetchUser, fetchPosts])
.then(responses =>
Promise.all(responses.map(r => r.json()))
)
.then(([user, posts]) => {
console.log('Пользователь:', user);
console.log('Посты:', posts);
});Динамическая цепочка обработки:
function processData(data) {
return Promise.resolve(data)
.then(validate)
.then(enrich)
.then(transform)
.then(result => {
console.log('Обработка завершена:', result);
return result;
});
}Обработка с таймаутом:
function withTimeout(promise, timeout) {
return Promise.race([
promise,
new Promise((_, reject) =>
setTimeout(() => reject(new Error('Таймаут')), timeout)
)
]);
}
withTimeout(fetch('/api/data'), 5000)
.then(response => response.json())
.catch(error => console.error('Ошибка:', error));Трансформация ошибок:
apiCall()
.then(data => process(data))
.catch(error => {
if (error.status === 404) {
return getDefaultData();
}
throw error;
})
.then(data => console.log('Результат:', data));Обработка с сайд-эффектами:
let cache = {};
function getCachedData(key) {
if (cache[key]) {
return Promise.resolve(cache[key]);
}
return fetchData(key)
.then(data => {
cache[key] = data;
return data;
});
}