Promise создается с помощью конструктора new Promise(), который принимает функцию-исполнитель с двумя параметрами: resolve и reject. Функция-исполнитель выполняется немедленно при создании Promise и должна вызвать resolve(value) при успешном завершении или reject(error) при ошибке.
Базовый синтаксис:
const myPromise = new Promise((resolve, reject) => {
// Асинхронная операция
if (успех) {
resolve(результат);
} else {
reject(ошибка);
}
});Ключевые моменты:
Создание Promise — это фундаментальный навык в асинхронном программировании JavaScript. Promise представляет собой объект, который может завершиться успешно с некоторым значением или завершиться с ошибкой.
Promise создается с помощью конструктора new Promise(), который принимает одну функцию, называемую функцией-исполнителем:
const myPromise = new Promise((resolve, reject) => {
// Функция-исполнитель
// resolve(value) - при успешном завершении
// reject(error) - при ошибке
});const promise = new Promise((resolve, reject) => {
setTimeout(() => {
const randomNumber = Math.random();
if (randomNumber > 0.5) {
resolve(`Успех! Число: ${randomNumber}`);
} else {
reject(new Error(`Ошибка! Число слишком маленькое: ${randomNumber}`));
}
}, 1000);
});
// Использование
promise
.then(result => console.log(result))
.catch(error => console.error(error.message));Функция resolve вызывается при успешном завершении операции:
const successPromise = new Promise((resolve, reject) => {
// Симуляция асинхронной операции
setTimeout(() => {
const data = { id: 1, name: 'Пользователь' };
resolve(data); // Передаем результат
}, 1000);
});
successPromise.then(user => {
console.log('Получен пользователь:', user);
});Функция reject вызывается при ошибке в операции:
const errorPromise = new Promise((resolve, reject) => {
setTimeout(() => {
const errorMessage = 'Сетевая ошибка';
reject(new Error(errorMessage)); // Передаем ошибку
}, 1000);
});
errorPromise.catch(error => {
console.error('Произошла ошибка:', error.message);
});function fetchUrl(url) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.onload = function() {
if (xhr.status === 200) {
resolve(xhr.responseText);
} else {
reject(new Error(`Ошибка HTTP: ${xhr.status}`));
}
};
xhr.onerror = function() {
reject(new Error('Ошибка сети'));
};
xhr.send();
});
}
// Использование
fetchUrl('/api/data')
.then(data => console.log('Данные получены:', data))
.catch(error => console.error('Ошибка:', error.message));function readFile(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = function(event) {
resolve(event.target.result);
};
reader.onerror = function(error) {
reject(new Error('Ошибка чтения файла'));
};
reader.readAsText(file);
});
}
// Использование
const fileInput = document.querySelector('input[type="file"]');
fileInput.addEventListener('change', function(event) {
const file = event.target.files[0];
if (file) {
readFile(file)
.then(content => console.log('Содержимое файла:', content))
.catch(error => console.error('Ошибка:', error.message));
}
});// Оригинальная функция с обратным вызовом
function delayCallback(ms, callback) {
setTimeout(() => {
callback(null, `Прошло ${ms} миллисекунд`);
}, ms);
}
// Преобразование в Promise
function delayPromise(ms) {
return new Promise((resolve, reject) => {
delayCallback(ms, (error, result) => {
if (error) {
reject(error);
} else {
resolve(result);
}
});
});
}
// Использование
delayPromise(2000)
.then(message => console.log(message))
.catch(error => console.error(error));const correctPromise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Первый вызов'); // Только этот вызов имеет значение
resolve('Второй вызов'); // Игнорируется
}, 1000);
});
// ❌ Неправильно - множественные вызовы
const wrongPromise = new Promise((resolve, reject) => {
resolve('Первый результат');
reject('Ошибка'); // Игнорируется
});// ❌ Исключение может быть потеряно
const unsafePromise = new Promise((resolve, reject) => {
throw new Error('Ошибка в функции-исполнителе');
// Это исключение не будет поймано!
});
// ✅ Правильная обработка исключений
const safePromise = new Promise((resolve, reject) => {
try {
// Код, который может бросить исключение
const result = riskyOperation();
resolve(result);
} catch (error) {
reject(error);
}
});
// Или использование .catch()
unsafePromise.catch(error => {
console.error('Поймано исключение:', error.message);
});console.log('1. Перед созданием Promise');
const promise = new Promise((resolve, reject) => {
console.log('2. Внутри функции-исполнителя');
setTimeout(() => {
console.log('4. Асинхронная операция завершена');
resolve('Результат');
}, 1000);
});
console.log('3. После создания Promise');
promise.then(result => {
console.log('5. Получен результат:', result);
});
// Вывод:
// 1. Перед созданием Promise
// 2. Внутри функции-исполнителя
// 3. После создания Promise
// 4. Асинхронная операция завершена
// 5. Получен результат: Результат// ❌ Неправильно - передача нескольких аргументов
const badPromise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('первый', 'второй', 'третий'); // Только 'первый' будет передан
}, 1000);
});
// ✅ Правильно - передача объекта
const goodPromise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve({
first: 'первый',
second: 'второй',
third: 'третий'
});
}, 1000);
});// ❌ Неправильно - потеря Promise в цепочке
function processData() {
return new Promise((resolve, reject) => {
getData()
.then(data => {
// Забыли return
transformData(data); // Это не Promise!
})
.then(result => {
// result будет undefined
resolve(result);
});
});
}
// ✅ Правильно - возврат Promise
function processData() {
return new Promise((resolve, reject) => {
getData()
.then(data => {
return transformData(data); // Возвращаем Promise
})
.then(result => {
resolve(result);
});
});
}Создание Promise — это важный навык для работы с асинхронным кодом в JavaScript. Понимание правильного способа создания Promise позволяет создавать более надежный и предсказуемый асинхронный код.
Хотите больше статей для подготовки к собеседованиям? Подписывайтесь на EasyAdvice, добавляйте сайт в закладки и совершенствуйтесь каждый день 💪