1.89M
Category: programmingprogramming

Асинхронность в JS

1.

Асинхронность в JS
• Ад коллбэков
• Рантайм JS
• Event Loop
• Промисы – синтаксис, цепочка, перехват ошибок
• Async/Await – синтаксис, цепочка, перехват ошибок
• Параллельное выполнение асинхронных запросов
• Верхнеуровневый await

2.

Ад коллбэков (callback hell)
Для обеспечения возможности общения
клиента с серверами используются AJAX (от
англ. "Asynchronous JavaScript and XML”)
запросы.
До появления промисов и async/await
использовались конструкции XMLHttpRequest,
главный минус которых заключался в том, что
при наличии зависимости одного запроса от
предыдущего создавалась пирамидальная
структура запросов вследствие обработки
каждого нового запроса в коллбэке, образуя
таким образом множественность вложенных
коллбэков.

3.

Ад коллбэков можно узнать по
формированию “пирамидки” по
вертикальной оси кода.
Для того, чтобы сделать
структуру запросов “плоской”
(убрать вложенность) была
внедрена конструкция
промисов.
Но перед разбором AJAX-запросов с
использованием промисов рассмотрим
работу рантайма JS, в частности - Event
Loop.

4.

Рантайм JS в браузере
Движок JS
Хранение
референсов (объекты,
функции)
Куча
Web APIs
Выполнение кода,
примитивные данные
Стек
Цикл
событий
fetch
timeout
geolocation
Очередь
click
load
timer
и другие

5.

Event Loop
Стек
Web APIs
1
2
3
5
8
Очередь микротасок
6
9
Очередь макротасок
7
Глобальный контекст
4

6.

Промисы: понятие и синтаксис
Понятие
Промис - это особый объект, используемый в
качестве плейсхолдера для будущего значения
завершенной асинхронной операции.
Промис - это контейнер для будущего значения
(не установленного на настоящий момент)
Синтаксис

7.

Промисы: пример

8.

Возможные состояния промиса
Pending
Settled
Fulfilled
Rejected
Из состояния Settled в другое промис может перейти только
единожды. Все попытки изменить состояние промиса после
первого изменения будут проигнорированы.

9.

Промисы: цепочка
promise(...)
.then(...)
.then(...)
.then(...)
Если очередной then вернул промис, то далее по
цепочке будет передан не сам этот промис, а его
результат.

10.

Перехват ошибок
При возникновении ошибки – она
отправляется в ближайший обработчик
onRejected.
Такой обработчик нужно поставить через
второй аргумент .then(..., onRejected) или,
что то же самое, через .catch(onRejected).

11.

Async/Await
• Важно отметить, что async-функции работают поверх промисов.
• Эти функции не являются принципиально другими концепциями.
• Async-функции были задуманы как альтернатива коду, использующему промисы.
• Используя конструкцию async/await, можно полностью избежать использование цепочек
промисов.
• С помощью async-функций возможно организовать работу с асинхронным кодом в
синхронном стиле.
• Async - это синтаксический сахар промисов.

12.

Async/await: Синтаксис

13.

Цепочка промисов
Async/await
=

14.

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

15.

Параллельное выполнение промисов
Комбинаторы промисов
Promise.all
Promise.race
Завершен, когда все
выполнены
Один reject - все игнорируются
Promise.allSettled
Завершен, когда все
выполнены
Без разницы, reject или fulfill
Promise.any
Завершен, когда один fulfill
Завершен, когда выполнен
самый быстрый (даже reject)

16.

Разница между комбинаторами
промисов и множественными
последовательными
await/промисами в скорости
запроса данных с сервера
Последовательное выполнение
692 мс
Параллельное выполнение
164 мс

17.

18.

Top-level await
Раньше ключевое слово await
можно было использовать
только в async функциях, что
иногда требовало прибегать к
использованию конструкции
IIFE (immediately invoked
function expression)

19.

В стандарт ES2022 был включен верхнеуровневый await (toplevel await), который доступен в скриптах типа module.
import
index.html
import
index.js
await.js
English     Русский Rules