JavaScript — это однопоточный язык, то есть он имеет только один основной поток выполнения, и код обычно выполняется последовательно сверху вниз. Однако в JavaScript реализованы концепции асинхронности и цикла событий для эффективной обработки неблокирующих операций, таких как операции ввода-вывода и сетевые запросы, без замораживания всего приложения.
Промисы создаются всякий раз, когда мы имеем дело с асинхронным блоком кода, и их необходимо использовать. Затем .catch и async await — это два способа использования промиса (один из них — цепочка промисов).
Итак, в этом блоге мы собираемся узнать о промисах и о том, как мы можем их использовать, используя async/await
.
Что такое обещания?
Промисы — это объекты, представляющие значение, которое может быть еще недоступно, но станет доступно в какой-то момент в будущем. Они используются для обработки асинхронных операций, таких как получение данных с сервера.
Обещания имеют три состояния: ожидание, выполнение и отклонение. Когда обещание выполнено, это означает, что операция прошла успешно и обещанное значение доступно. Когда обещание отклонено, это означает, что операция не удалась и выдается ошибка.
Давайте разберемся с состоянием промисов на соответствующем примере:
Ожидание обещаний
Состояние «Ожидание» промиса — это начальное состояние, когда промис создан, но еще не решен или отклонен. Он представляет собой период, в течение которого выполняется асинхронная операция, и обещание ожидает завершения этой операции.
Разберемся на примере:
Из приведенного выше кода:
import axios from "axios";
: Эта строка добавляет в ваш код Axios, инструмент для отправки веб-запросов.let response = axios.get("<https://jsonplaceholder.typicode.com/users>");
: эта строка отправляет запрос на веб-адрес. Результатом этого запроса, называемогоresponse
, является обещание. Думайте об этом как о билете, в котором говорится: «Я получу для вас данные».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));
Выход :
Из приведенного выше кода:
axios.get("<https://jsonplaceholder.typicode.com/users/>")
: эта строка отправляет HTTP-запрос GET на URL-адрес **«https://jsonplaceholder.typicode.com/users/**» с использованием библиотеки Axios. Он инициирует запрос на получение данных..then((res) => { console.log(res.data[0]); })
: После успешного запроса этот код обрабатывает ответ (res
), записывая данные первого пользователя из ответа JSON (res.data[0]
) на консоль. В этом случае он печатает данные первого пользователя..catch((err) => console.log("Page status : "+err.response.status))
: если во время запроса возникает ошибка, этот код обрабатывает ее, записывая сообщение в консоль. Он специально проверяет свойствоresponse.status
объекта ошибки, чтобы распечатать код состояния HTTP ответа. Это может помочь определить, что пошло не так с запросом.
Отклоненное состояние обещаний
Состояние «Отклонено» промиса указывает на то, что во время асинхронной операции, связанной с промисом, произошла ошибка. Это означает, что операция не завершилась успешно и возникла проблема или сбой.
Разберемся на примере:
Из приведенного выше кода:
- Мы видим, что
.then
не выполняется из-за ошибкиAPI
. - Из-за этого выполнение переходит к строке 8, чтобы выполнить статус страницы
Page status : 404
, что означает, что страница не найдена илиrejected
.
Обработка нескольких обещаний
Обработка нескольких обещаний в JavaScript — распространенный сценарий, особенно при работе с асинхронными операциями, такими как получение данных из нескольких источников или выполнение нескольких вызовов API.
Здесь мы собираемся использовать Цепочку обещаний для обработки нескольких запросов и увидим, почему это неправильный метод для выполнения Цепочки обещаний.
Цепочка обещаний
Цепочка обещаний с помощью Axios — это метод, который позволяет вам управлять последовательностью асинхронных HTTP-запросов чистым и организованным образом.
Axios возвращает Promises для HTTP-запросов, что делает его хорошо подходящим для цепочки. Вот как работает цепочка обещаний с Axios:
- Начиная с начального запроса. Вы начинаете с начального запроса Axios, который представляет собой первую асинхронную операцию HTTP в вашей последовательности.
- Объединение
.then()
: после первоначального запроса Axios вы можете объединить один или несколько методов.then()
. Каждый метод.then()
определяет, что должно произойти, когда предыдущий запрос Axios будет разрешен (т. е. HTTP-запрос будет успешным). Вы передаете функцию обратного вызова.then()
, чтобы определить это поведение. - Объединение
.catch()
. Вы также можете объединить метод.catch()
после методов.then()
. Метод.catch()
определяет, что делать, если какой-либо из предыдущих запросов Axios в цепочке обнаружил ошибку (например, сетевую ошибку или неуспешный код состояния HTTP). Как и.then()
, вы передаете функцию обратного вызова.catch()
для обработки ошибок. - Возврат новых обещаний. В каждом обратном вызове
.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:
- Ад обратных вызовов. Цепочки обещаний могут стать трудными для чтения, если они глубоко вложены, что приводит к так называемому «аду обратных вызовов» или «пирамиде гибели».
- Обработка ошибок. Обработка ошибок в длинных цепочках обещаний может быть сложной задачей, поскольку вам нужно добавить
.catch()
в конце, что приводит к разбросанию кода обработки ошибок. - Читаемость и удобство сопровождения. Длинные и сложные цепочки могут сделать код менее читабельным и усложнить его поддержку.
- Негибкость. Цепочки являются последовательными, поэтому они могут быть не лучшим выбором для независимых асинхронных операций.
- Накладные расходы на производительность: каждый
.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();
В этом коде:
- Импортируем библиотеку Axios, используя
require('axios')
. - Мы определяем функцию
async
под названиемfetchData
, которая будет отправлять HTTP-запрос GET к'<https://api.example.com/data'
›. - Внутри блока
try
мы используемawait
перед вызовомaxios.get
. Это указывает JavaScript приостановить выполнение функции до тех пор, пока обещание, возвращаемоеaxios.get
, не будет разрешено или отклонено. Благодаря этому код выглядит синхронным, хотя за кулисами он асинхронен. - Мы можем получить доступ к данным из ответа, используя
response.data
, а затем обработать или работать с данными по мере необходимости. - В блоке
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: это более понятный и читаемый способ обработки таких обещаний. Он выглядит как обычный синхронный код, но по-прежнему обрабатывает асинхронные операции одну за другой.