Зачем нужна асинхронность

Бекенд-разработчики обычно пишут синхронный код. В нём команды исполняются одна за другой:

# ...
grand_total = sum(cart_products.values())
print(grand_total)
# ...

Ничего не требуется предпринимать, если синхронный код работает быстро. Проблемы возникают, когда он подвисает и не реагирует на команды пользователя. Синхронный email-клиент не сможет реагировать на нажатие кнопок, пока он скачивает почту. А скачивание тоже происходит синхронно: пока не ответит первый email-провайдер, клиент не отправит запрос второму.

Асинхронное программирование позволяет сделать несколько быстрых действий, пока не завершится долгое. Email-клиент может показывать пользователю скачанные письма, пока новая почта асинхронно загружается. Вот как это выглядит в псевдокоде:

while True:
  download_progress = download_emails_step_by_step(download_progress)

  click = read_click()
    # ...

Асинхронным этот код делает функция, которая названа download_emails_step_by_step. Она скачивает не всю почту за раз, а понемногу. Скачав кусочек, она возвращает управление циклу while True. Этот цикл дальше запустит read_click, которая вернёт клик пользователя, если он был, и None , если не было. Другие функции в этом цикле аналогичные: они делают небольшое действие, останавливаются, возвращают управление циклу, который их снова запускает позже.

Обычные функции в Питоне работают не так, как это принято в асинхронном программировании. Функция input, например, ждёт пользовательского ввода и может долго не возвращать управление вызвавшему её коду. Поэтому в язык добавили библиотеку asyncio, которая содержит инструменты для работы с асинхронным кодом и асинхронные эквиваленты синхронных функций (например, sleep).

Привычные инструменты ломают асинхронный код

Рассмотрим ещё один пример. Есть сервер, который возвращает координаты перемещения автобусов в реальном времени. Для каждого автобуса ведётся трансляция его координат. Асинхронный код поможет отрисовать маршрут движения автобуса до того, как закончится трансляция координат. Нам не обязательно даже знать, закончится ли она, потому что данные обрабатываются по частям, небольшими порциями.

Асинхронный код подходит всегда, когда есть несколько потоков ввода, и достаточно обработать только часть данных, но быстро и одновременно у всех потоков. Для решения этого класса задач и нужен асинхронный Python.

Если потоков данных много, то спасет асинхронность