Ты наконец-то поймешь асинхронность в JS
- суббота, 17 февраля 2024 г. в 00:00:13
Привет, друзья! Сегодня мы поговорим о том, что такое асинхронность в JavaScript и как она работает. Это одна из тех вещей, которые кажутся сложными, но на самом деле довольно просты, как только разберешься.
Синхронный код - это код, который выполняется последовательно, один за другим. Ничего сложного, просто пошаговое выполнение. Для примера, вот как может выглядеть синхронный код:
console.log('Шаг 1');
console.log('Шаг 2');
console.log('Шаг 3');
А асинхронный код может выполняться параллельно с другими задачами. Это как многозадачность в нашей повседневной жизни: вы можете делать несколько вещей одновременно. Вот пример асинхронного кода:
console.log('Шаг 1');
setTimeout(function() {
console.log('Шаг 2');
}, 2000);
console.log('Шаг 3');
В примере выше мы использовали setTimeout
, чтобы задержать выполнение определенной функции на две секунды. Заметьте, что функция в setTimeout
выполняется асинхронно, а остальной код продолжает выполняться без ожидания.
Конечно, введем более детальные примеры и разберем, какие методы являются микрозадачами, а какие макрозадачами.
В JavaScript некоторые операции создают микрозадачи, а некоторые - макрозадачи. Давайте рассмотрим примеры.
Микрозадачи обычно связаны с операциями, связанными с промисами. Вот несколько примеров операций, создающих микрозадачи:
Разрешение или отклонение промиса с помощью методов .then()
, .catch()
и .finally()
.
Использование async/await
в асинхронных функциях.
Давайте рассмотрим пример с использованием промисов:
console.log('Начало');
Promise.resolve()
.then(() => console.log('Это микрозадача'))
.then(() => console.log('Это еще одна микрозадача'));
console.log('Конец');
Этот код создает две микрозадачи с помощью методов .then()
. Заметьте, что они выполняются после основной задачи, несмотря на то, что они добавляются в очередь раньше.
Макрозадачи обычно связаны с более крупными операциями или событиями в JavaScript, такими как выполнение скриптов, обработка событий DOM или выполнение кода в таймауте. Вот несколько примеров операций, создающих макрозадачи:
Выполнение скрипта.
Обработка событий DOM.
Выполнение кода в таймауте с помощью setTimeout()
или setInterval()
.
Рассмотрим пример с использованием setTimeout()
:
console.log('Начало');
setTimeout(() => {
console.log('Это макрозадача');
}, 0);
console.log('Конец');
Этот код создает макрозадачу с помощью функции setTimeout()
. Заметьте, что она добавляется в очередь после основной задачи и даже после микрозадач.
В рамках итерации цикла сначала выполняются микрозадачи, затем — макрозадачи. Пока есть задачи — цикл их выполняет, а когда их нет — ожидает новых задач.
Понимание различия между микрозадачами и макрозадачами важно для эффективного управления асинхронным кодом в JavaScript. Это помогает предсказать порядок выполнения операций и избежать неожиданных результатов.
Как происходит выполнение этих задач? Здесь на сцену выходи Event Loop — это ключевой компонент в архитектуре JavaScript, который управляет порядком выполнения асинхронных операций. Он следит за стеком вызовов и очередями задач, обеспечивая последовательное выполнение кода и асинхронных операций.
Асинхронный код позволяет создавать более отзывчивые и эффективные веб-приложения, не замораживая интерфейс. Он позволяет выполнять задачи в фоновом режиме, не блокируя основной поток выполнения. Улучшает производительность приложений, особенно в сценариях, где требуется обработка большого количества данных или выполнение длительных операций.
Теперь, когда мы понимаем основы асинхронного программирования, давайте рассмотрим некоторые ключевые асинхронные методы и их особенности.
Promise: Promise — это объект, представляющий конечное состояние асинхронной операции. Он может находиться в одном из трех состояний: ожидание (pending), выполнено (fulfilled) или отклонено (rejected). Promise позволяет зарегистрировать обратные вызовы (callbacks), которые будут вызваны, когда Promise перейдет в состояние выполнено или отклонено. Пример использования Promise:
console.log('Начало');
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Выполнено!');
}, 2000);
});
promise.then((result) => {
console.log(result);
}).catch((error) => {
console.error(error);
});
console.log('Конец');
В этом примере мы создаем Promise, который выполняется через две секунды. Затем мы используем метод .then()
, чтобы обработать результат выполнения Promise. Заметьте, что код после создания Promise не ждет его выполнения и продолжает работу.
async/await: async/await
— это синтаксический сахар над Promise, который позволяет писать асинхронный код, выглядящий как синхронный. Ключевое слово async
делает функцию асинхронной, а await
используется для ожидания разрешения Promise. Пример использования async/await
:
console.log('Начало');
async function myAsyncFunction() {
try {
const result = await new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Выполнено!');
}, 2000);
});
console.log(result);
} catch (error) {
console.error(error);
}
}
myAsyncFunction();
console.log('Конец');
Здесь мы определяем асинхронную функцию, которая ожидает выполнения Promise с помощью ключевого слова await
. Это позволяет нам писать код, который выглядит как синхронный, но на самом деле выполняется асинхронно. Обработка ошибок осуществляется с помощью блока try/catch
.
Читаемость кода: Promise и async/await делают асинхронный код более читаемым и понятным, особенно при выполнении сложных последовательностей операций.
Управление ошибками: Promise предоставляет удобный способ обработки ошибок с помощью метода .catch()
, а async/await позволяет использовать блок try/catch
для обработки ошибок.
Избегание callback hell: Использование цепочек Promise или async/await позволяет избежать так называемой "callback hell" - ситуации, когда множество вложенных обратных вызовов делают код трудным для чтения и отладки.
Надеюсь, что этот более глубокий обзор асинхронного программирования в JavaScript помог вам лучше понять, как использовать асинхронные методы, а также какие преимущества они предоставляют.
Поиграться с асинхронностью можно на этом сайте https://www.jsv9000.app/