async и await в JavaScript: как использовать асинхронность в JS

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

Создание асинхронной функции с async

Ключевое слово async добавляется перед объявлением функции:

async function fetchData() {
    return 'Данные получены';
}

Такая функция всегда возвращает промис, даже если внутри просто возвращается значение:

fetchData().then(console.log); // Вывод: Данные получены

Ожидание результата с await

await приостанавливает выполнение функции до получения результата промиса. Работает только внутри функций, объявленных с async.

async function fetchData() {
    const response = await fetch('https://jsonplaceholder.typicode.com/posts/1');
    const data = await response.json();
    console.log(data);
}

В этом примере fetch возвращает промис, который обрабатывается через await, а затем второй await обрабатывает распарсенный ответ.

Обработка ошибок с try/catch

Для перехвата ошибок в асинхронных функциях удобно использовать блок try/catch:

async function fetchData() {
    try {
        const response = await fetch('https://jsonplaceholder.typicode.com/posts/1');
        if (!response.ok) {
            throw new Error(`Ошибка HTTP: ${response.status}`);
        }
        const data = await response.json();
        console.log(data);
    } catch (error) {
        console.error('Ошибка:', error);
    }
}

Совместное использование async/await и Promise.all

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

async function fetchMultiple() {
    const [post, user] = await Promise.all([
        fetch('https://jsonplaceholder.typicode.com/posts/1').then(res => res.json()),
        fetch('https://jsonplaceholder.typicode.com/users/1').then(res => res.json())
    ]);
    
    console.log('Пост:', post);
    console.log('Пользователь:', user);
}

async/await против then/catch

async/await упрощает написание последовательного кода, убирает цепочки then и делает логику более очевидной. Однако then/catch все еще используется, особенно при работе с чистыми промисами без оберток в функции.

Пример с then/catch:

fetch('https://jsonplaceholder.typicode.com/posts/1')
    .then(response => response.json())
    .then(data => console.log(data))
    .catch(error => console.error('Ошибка:', error));

Тот же пример с async/await:

async function fetchData() {
    try {
        const response = await fetch('https://jsonplaceholder.typicode.com/posts/1');
        const data = await response.json();
        console.log(data);
    } catch (error) {
        console.error('Ошибка:', error);
    }
}

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