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

Промисы создаются всякий раз, когда мы имеем дело с асинхронным блоком кода, и их необходимо использовать. Затем .catch и async await — это два способа использования промиса (один из них — цепочка промисов).

Итак, в этом блоге мы собираемся узнать о промисах и о том, как мы можем их использовать, используя async/await.

Что такое обещания?

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

Обещания имеют три состояния: ожидание, выполнение и отклонение. Когда обещание выполнено, это означает, что операция прошла успешно и обещанное значение доступно. Когда обещание отклонено, это означает, что операция не удалась и выдается ошибка.

Давайте разберемся с состоянием промисов на соответствующем примере:

Ожидание обещаний

Состояние «Ожидание» промиса — это начальное состояние, когда промис создан, но еще не решен или отклонен. Он представляет собой период, в течение которого выполняется асинхронная операция, и обещание ожидает завершения этой операции.

Разберемся на примере:

Из приведенного выше кода:

  1. import axios from "axios";: Эта строка добавляет в ваш код Axios, инструмент для отправки веб-запросов.
  2. let response = axios.get("<https://jsonplaceholder.typicode.com/users>");: эта строка отправляет запрос на веб-адрес. Результатом этого запроса, называемого response, является обещание. Думайте об этом как о билете, в котором говорится: «Я получу для вас данные».
  3. console.log(response);: Это записывает на консоль обещание, которое представляет собой не фактические данные, которые вам нужны, а способ получить их позже.

Выполненное состояние обещаний

Состояние «Выполнено» обещания указывает на то, что асинхронная операция, связанная с обещанием, завершилась успешно и доступен результат (или значение). Другими словами, Обещание сделало то, что должно было сделать, и теперь оно хранит в себе результаты этой операции.

Разберемся на примере:

import axios from "axios";

axios
  .get("https://jsonplaceholder.typicode.com/users/")
  .then((res) => {
    console.log(res.data[0]);
  })
  .catch((err) => console.log("Page status : "+err.response.status));

Выход :

Из приведенного выше кода:

  1. axios.get("<https://jsonplaceholder.typicode.com/users/>"): эта строка отправляет HTTP-запрос GET на URL-адрес **«https://jsonplaceholder.typicode.com/users/**» с использованием библиотеки Axios. Он инициирует запрос на получение данных.
  2. .then((res) => { console.log(res.data[0]); }): После успешного запроса этот код обрабатывает ответ (res), записывая данные первого пользователя из ответа JSON (res.data[0]) на консоль. В этом случае он печатает данные первого пользователя.
  3. .catch((err) => console.log("Page status : "+err.response.status)): если во время запроса возникает ошибка, этот код обрабатывает ее, записывая сообщение в консоль. Он специально проверяет свойство response.status объекта ошибки, чтобы распечатать код состояния HTTP ответа. Это может помочь определить, что пошло не так с запросом.

Отклоненное состояние обещаний

Состояние «Отклонено» промиса указывает на то, что во время асинхронной операции, связанной с промисом, произошла ошибка. Это означает, что операция не завершилась успешно и возникла проблема или сбой.

Разберемся на примере:

Из приведенного выше кода:

  1. Мы видим, что .then не выполняется из-за ошибки API.
  2. Из-за этого выполнение переходит к строке 8, чтобы выполнить статус страницы Page status : 404, что означает, что страница не найдена или rejected.

Обработка нескольких обещаний

Обработка нескольких обещаний в JavaScript — распространенный сценарий, особенно при работе с асинхронными операциями, такими как получение данных из нескольких источников или выполнение нескольких вызовов API.

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

Цепочка обещаний

Цепочка обещаний с помощью Axios — это метод, который позволяет вам управлять последовательностью асинхронных HTTP-запросов чистым и организованным образом.

Axios возвращает Promises для HTTP-запросов, что делает его хорошо подходящим для цепочки. Вот как работает цепочка обещаний с Axios:

  1. Начиная с начального запроса. Вы начинаете с начального запроса Axios, который представляет собой первую асинхронную операцию HTTP в вашей последовательности.
  2. Объединение.then(): после первоначального запроса Axios вы можете объединить один или несколько методов .then(). Каждый метод .then() определяет, что должно произойти, когда предыдущий запрос Axios будет разрешен (т. е. HTTP-запрос будет успешным). Вы передаете функцию обратного вызова .then(), чтобы определить это поведение.
  3. Объединение.catch(). Вы также можете объединить метод .catch() после методов .then(). Метод .catch() определяет, что делать, если какой-либо из предыдущих запросов Axios в цепочке обнаружил ошибку (например, сетевую ошибку или неуспешный код состояния HTTP). Как и .then(), вы передаете функцию обратного вызова .catch() для обработки ошибок.
  4. Возврат новых обещаний. В каждом обратном вызове .then() или .catch() у вас есть возможность вернуть новое обещание, например другой запрос Axios. Это позволяет вам связывать дополнительные HTTP-запросы или логику обработки ошибок.

Вот пример цепочки обещаний с помощью Axios:

axios.get('<https://api.example.com/data>')
  .then((response) => {
    if (response.status !== 200) {
      throw new Error('Request failed with status: ' + response.status);
    }
    return response.data;
  })
  .then((data) => {
    // Process the data from the first request
    console.log(data);

    // Return a new Axios request
    return axios.get('<https://api.example.com/other-data>');
  })
  .then((otherDataResponse) => {
    // Process the data from the second request
    console.log(otherDataResponse.data);
  })
  .catch((error) => {
    // Handle errors that occurred in the chain
    console.error(error);
  });

В этом примере:

  • Первоначальный запрос axios.get извлекает данные с удаленного сервера.
  • Первый .then() обрабатывает ответ и проверяет, не равен ли код состояния 200 (т. е. не успешен). Если нет, то выдает ошибку.
  • Второй .then() обрабатывает данные первого запроса и возвращает новый запрос Axios для «других данных».
  • Третий .then() обрабатывает ответ на второй запрос.
  • .catch() в конце обрабатывает любые ошибки, возникшие в цепочке.

Проблема с цепочкой обещаний

Потенциальные проблемы с цепочкой обещаний в JavaScript:

  1. Ад обратных вызовов. Цепочки обещаний могут стать трудными для чтения, если они глубоко вложены, что приводит к так называемому «аду обратных вызовов» или «пирамиде гибели».
  2. Обработка ошибок. Обработка ошибок в длинных цепочках обещаний может быть сложной задачей, поскольку вам нужно добавить .catch() в конце, что приводит к разбросанию кода обработки ошибок.
  3. Читаемость и удобство сопровождения. Длинные и сложные цепочки могут сделать код менее читабельным и усложнить его поддержку.
  4. Негибкость. Цепочки являются последовательными, поэтому они могут быть не лучшим выбором для независимых асинхронных операций.
  5. Накладные расходы на производительность: каждый .then() вносит небольшой накладной расход на производительность в длинных цепочках.

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

Асинхронный/ожидающий

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

Синтаксис async/await был представлен в спецификации ECMAScript 2017 (ES8).

Это особенно полезно для обработки обещаний и упрощения чтения и управления асинхронными операциями. axios – это популярная библиотека для выполнения HTTP-запросов в JavaScript. Ее можно использовать с async/await для создания более чистого и читаемого кода.

Вот пример использования async/await с axios:

const axios = require('axios'); // Import the Axios library

// Define an async function to make an HTTP request
async function fetchData() {
  try {
    // Use await to make the HTTP GET request
    const response = await axios.get('<https://api.example.com/data>');

    // Access the data from the response
    const data = response.data;

    // Process and work with the data
    console.log(data);
  } catch (error) {
    // Handle any errors that occurred during the request
    console.error(error);
  }
}

// Call the async function
fetchData();

В этом коде:

  1. Импортируем библиотеку Axios, используя require('axios').
  2. Мы определяем функцию async под названием fetchData, которая будет отправлять HTTP-запрос GET к '<https://api.example.com/data'›.
  3. Внутри блока try мы используем await перед вызовом axios.get. Это указывает JavaScript приостановить выполнение функции до тех пор, пока обещание, возвращаемое axios.get, не будет разрешено или отклонено. Благодаря этому код выглядит синхронным, хотя за кулисами он асинхронен.
  4. Мы можем получить доступ к данным из ответа, используя response.data, а затем обработать или работать с данными по мере необходимости.
  5. В блоке catch мы обрабатываем любые ошибки, которые могут возникнуть во время HTTP-запроса. Здесь вы можете решать проблемы с сетью, ошибки сервера или любые другие ошибки, связанные с запросом.

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

Обработка нескольких обещаний с помощью Async/Await

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

async function fetchData() {
  try {
    // Initial Axios request
    const response1 = await axios.get('https://api.example.com/data');
    
    if (response1.status !== 200) {
      throw new Error('Request failed with status: ' + response1.status);
    }

    const data1 = response1.data;
    console.log(data1);

    // Second Axios request
    const response2 = await axios.get('https://api.example.com/other-data');
    const data2 = response2.data;
    console.log(data2);

    // Continue with more operations if needed...

  } catch (error) {
    // Handle errors that occurred in the try block
    console.error(error);
  }
}

// Call the async function
fetchData();

В этом примере async/await:

  • Мы определяем функцию async под названием fetchData для управления последовательностью асинхронных операций.
  • Внутри блока try мы используем await для приостановки выполнения и ожидания завершения каждого запроса Axios. В случае возникновения ошибки управление передается блоку catch.
  • После успешного завершения каждого запроса Axios мы обрабатываем данные ответа и протоколируем их.
  • При необходимости вы можете продолжить выполнение дополнительных асинхронных операций в блоке try.

Блок catch обрабатывает любые ошибки, возникшие в блоке try, включая ошибки, возникающие явно или те, которые могут возникнуть во время запросов Axios.

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

Заключение

Проще говоря:

  • Цепочка обещаний: это похоже на серию обещаний, передающих результаты по цепочке, и вы указываете, что произойдет дальше, с помощью методов .then() и .catch().
  • Async/Await: это более понятный и читаемый способ обработки таких обещаний. Он выглядит как обычный синхронный код, но по-прежнему обрабатывает асинхронные операции одну за другой.