Promise — это объект в JavaScript, представляющий результат асинхронной операции. Он может находиться в одном из трех состояний: ожидание (pending), выполнено (fulfilled) или отклонено (rejected). Промисы упрощают работу с асинхронным кодом, избавляя от «ада обратных вызовов» и позволяя создавать цепочки асинхронных операций.
Основные преимущества:
Promise — это фундаментальная концепция асинхронного программирования в современном JavaScript. Он представляет собой объект, который может производить одно значение в будущем: либо разрешенное значение, либо причину, по которой оно не было разрешено (например, сетевая ошибка).
Promise может находиться в одном из трех состояний:
// Создание Promise
const myPromise = new Promise((resolve, reject) => {
// Асинхронная операция
setTimeout(() => {
const success = true;
if (success) {
resolve('Операция выполнена успешно');
} else {
reject('Произошла ошибка');
}
}, 1000);
});
// Использование Promise
myPromise
.then(result => console.log(result))
.catch(error => console.error(error));Обрабатывает успешное выполнение Promise:
fetch('/api/data')
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Ошибка:', error));Обрабатывает отклонение Promise:
fetch('/api/data')
.then(response => response.json())
.then(data => console.log(data))
.catch(error => {
console.error('Ошибка при загрузке данных:', error);
// Обработка ошибки
});Выполняется независимо от результата:
fetch('/api/data')
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error(error))
.finally(() => {
console.log('Запрос завершен');
// Скрыть индикатор загрузки
});Одно из главных преимуществ Promise — возможность создавать цепочки:
// Цепочка асинхронных операций
fetch('/api/user')
.then(response => response.json())
.then(user => fetch(`/api/profile/${user.id}`))
.then(response => response.json())
.then(profile => {
console.log('Профиль пользователя:', profile);
return profile;
})
.catch(error => {
console.error('Ошибка в цепочке:', error);
});Выполняет несколько Promise параллельно:
const promises = [
fetch('/api/users'),
fetch('/api/posts'),
fetch('/api/comments')
];
Promise.all(promises)
.then(responses => Promise.all(responses.map(res => res.json())))
.then(([users, posts, comments]) => {
console.log('Все данные загружены:', { users, posts, comments });
})
.catch(error => {
console.error('Ошибка при загрузке данных:', error);
});Возвращает результат первого завершившегося Promise:
const promises = [
fetch('/api/fast-endpoint'),
fetch('/api/slow-endpoint')
];
Promise.race(promises)
.then(response => response.json())
.then(data => {
console.log('Первый ответ:', data);
});Создают уже разрешенные или отклоненные Promise:
// Создание разрешенного Promise
const resolvedPromise = Promise.resolve('Успешное значение');
// Создание отклоненного Promise
const rejectedPromise = Promise.reject('Ошибка');
resolvedPromise.then(value => console.log(value)); // 'Успешное значение'
rejectedPromise.catch(error => console.error(error)); // 'Ошибка'// Параллельная загрузка данных пользователя
async function loadUserProfile(userId) {
try {
const [user, posts, followers] = await Promise.all([
fetch(`/api/users/${userId}`).then(res => res.json()),
fetch(`/api/users/${userId}/posts`).then(res => res.json()),
fetch(`/api/users/${userId}/followers`).then(res => res.json())
]);
return { user, posts, followers };
} catch (error) {
console.error('Ошибка при загрузке профиля:', error);
throw error;
}
}// Функция с обратным вызовом
function readFileCallback(filename, callback) {
// Симуляция асинхронной операции
setTimeout(() => {
if (filename) {
callback(null, `Содержимое файла: ${filename}`);
} else {
callback('Файл не найден', null);
}
}, 1000);
}
// Преобразование в Promise
function readFilePromise(filename) {
return new Promise((resolve, reject) => {
readFileCallback(filename, (error, data) => {
if (error) {
reject(error);
} else {
resolve(data);
}
});
});
}
// Использование
readFilePromise('example.txt')
.then(data => console.log(data))
.catch(error => console.error(error));// ❌ Плохо - ошибки в цепочке могут быть утеряны
fetch('/api/data')
.then(response => response.json())
.then(data => {
throw new Error('Ошибка в обработке данных');
})
.then(processedData => console.log(processedData));
// ✅ Хорошо - всегда добавляйте catch
fetch('/api/data')
.then(response => response.json())
.then(data => {
throw new Error('Ошибка в обработке данных');
})
.then(processedData => console.log(processedData))
.catch(error => console.error('Ошибка:', error));// ❌ Плохо - потеря значения в цепочке
fetch('/api/user')
.then(response => response.json())
.then(user => {
// Забыли return
fetch(`/api/profile/${user.id}`).then(res => res.json());
})
.then(profile => {
// profile будет undefined
console.log(profile);
});
// ✅ Хорошо - возвращаем Promise
fetch('/api/user')
.then(response => response.json())
.then(user => {
return fetch(`/api/profile/${user.id}`).then(res => res.json());
})
.then(profile => {
console.log(profile);
});Promise — это мощный инструмент для работы с асинхронным кодом в JavaScript. Понимание промисов позволяет создавать более читаемый, поддерживаемый и надежный код при работе с сетевыми запросами, таймерами и другими асинхронными операциями.
Хотите больше статей для подготовки к собеседованиям? Подписывайтесь на EasyAdvice, добавляйте сайт в закладки и совершенствуйтесь каждый день 💪