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

1. Основы асинхронности в JavaScript

В JavaScript выполнение задач по умолчанию однопоточное. Это значит, что код выполняется последовательно, и если одна операция занимает много времени, она блокирует выполнение остальных. Асинхронный код позволяет "не ждать" выполнения длительных операций и продолжать выполнение других задач.

Прежде чем появились async/await, программисты использовали обещания (promises) и колбэки для управления асинхронными операциями. Однако, promises не всегда легко читаемы, особенно при работе с множеством асинхронных операций. Для улучшения удобства работы с ними и был введён синтаксис async/await.

2. Как работают async и await

Ключевое слово async

Функция, помеченная как async, всегда возвращает обещание (promise). Это значит, что даже если функция явно не возвращает обещание, JavaScript автоматически обернёт её возвращаемое значение в Promise.

Пример простой асинхронной функции:


async function fetchData() {
    return "Данные загружены!";
}

fetchData().then(result => console.log(result));  // Выведет: Данные загружены!
Ключевое слово await

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

Пример использования await:



sync function fetchData() {    
    let data = await fetch('https://jsonplaceholder.typicode.com/todos/1');    
    let json = await data.json();  // Преобразуем ответ в JSON    
    console.log(json); 
} 
fetchData();   

В этом примере await приостанавливает выполнение до тех пор, пока данные не будут загружены, после чего они передаются в json() для дальнейшей обработки.

3. Обработка ошибок с async/await

Ошибки в асинхронных функциях можно обрабатывать с помощью блоков try/catch. Это позволяет сделать обработку ошибок более понятной и похожей на стандартные синхронные конструкции.

Пример обработки ошибок:


async function fetchData() {
    let data = await fetch('https://jsonplaceholder.typicode.com/todos/1');
    let json = await data.json();  // Преобразуем ответ в JSON
    console.log(json);
}
fetchData();

В данном примере, если запрос на сервер завершится неудачей, ошибка будет поймана в блоке catch.

4. Последовательное и параллельное выполнение с async/await

Использование await в последовательных вызовах может замедлить выполнение программы, так как каждый вызов будет ожидать завершения предыдущего. Однако можно запускать обещания параллельно и ждать их выполнения с помощью Promise.all().

Пример параллельного выполнения:


async function fetchData() {
    try {
        let response = await fetch('https://invalid-url');
        let data = await response.json();
        console.log(data);
    } catch (error) {
        console.error('Ошибка:', error);
    }
}
fetchData();

Здесь оба запроса выполняются параллельно, и результаты будут получены быстрее, чем при последовательных вызовах.

5. Заключение

Асинхронность в JavaScript с использованием async/await значительно упрощает работу с обещаниями и делает код более читаемым и предсказуемым. Основные моменты:

  • async делает функцию асинхронной и возвращает обещание.
  • await заставляет код "ждать" выполнения обещания.
  • Ошибки легко обрабатываются через try/catch.

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