Promise в JavaScript: как работать с промисами в JS

Promise — это встроенный объект в JavaScript, который представляет результат асинхронной операции. Промис может находиться в одном из трех состояний:

  • pending — ожидание (операция еще выполняется);
  • fulfilled — выполнено успешно (операция завершилась, результат получен);
  • rejected — выполнено с ошибкой (операция завершилась с ошибкой).

Промисы помогают писать асинхронный код в виде понятных цепочек, избегая глубокой вложенности, характерной для колбэк-функций.

Создание Promise

Promise создается с помощью конструктора, принимающего функцию с двумя аргументами: resolve и reject. Эти функции используются для смены состояния промиса:

const myPromise = new Promise((resolve, reject) => {
    setTimeout(() => {
        const success = true;

        if (success) {
            resolve('Операция завершена');
        } else {
            reject('Произошла ошибка');
        }
    }, 1000);
});

Обработка результата с then и catch

Успешное выполнение — then

myPromise.then(result => {
    console.log(result); // Операция завершена
});

Ошибка — catch

myPromise.catch(error => {
    console.error(error);
});

Цепочки then

Метод then возвращает новый промис, что позволяет выстраивать цепочки операций:

myPromise
    .then(result => {
        console.log(result);
        return 'Следующий шаг';
    })
    .then(step => {
        console.log(step);
    })
    .catch(error => {
        console.error('Ошибка:', error);
    });

Обработка в любом случае — finally

Метод finally выполняется после завершения промиса вне зависимости от результата:

myPromise
    .finally(() => {
        console.log('Операция завершена');
    });

Создание уже выполненного или отклоненного Promise

Выполненный промис

const resolvedPromise = Promise.resolve('Успешно');

Отклоненный промис

const rejectedPromise = Promise.reject('Ошибка');

Параллельное выполнение — Promise.all

Promise.all ожидает выполнения всех переданных промисов и возвращает массив результатов. Если хотя бы один промис завершится с ошибкой, весь Promise.all завершится с ошибкой:

const promise1 = Promise.resolve('Данные 1');
const promise2 = Promise.resolve('Данные 2');

Promise.all([promise1, promise2])
    .then(results => {
        console.log(results); // ['Данные 1', 'Данные 2']
    });

Ожидание первого результата — Promise.race

Promise.race возвращает результат первого выполненного промиса (неважно, успешно или с ошибкой):

Promise.race([
        fetch('https://jsonplaceholder.typicode.com/posts/1'),
        new Promise((_, reject) => setTimeout(() => reject('Timeout'), 5000))
    ])
    .then(response => console.log(response))
    .catch(error => console.error(error));

Преобразование кода с колбэками в промисы

Функции, работающие на колбэках, можно обернуть в промис:

function loadScript(src) {
    return new Promise((resolve, reject) => {
        const script = document.createElement('script');
        script.src = src;
        script.onload = () => resolve(`Скрипт ${src} загружен`);
        script.onerror = () => reject(new Error(`Ошибка загрузки скрипта ${src}`));
        document.head.append(script);
    });
}

Promise в JavaScript — это ключевой инструмент для работы с асинхронным кодом, который позволяет строить гибкие цепочки обработки данных, обрабатывать ошибки централизованно и комбинировать несколько асинхронных операций в один поток выполнения. Промисы — основа для современных механизмов вроде async/await, что делает их незаменимой частью работы с асинхронностью в языке.