Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Как работает await в Python
Определение
await — это оператор в Python, который приостанавливает выполнение асинхронной функции и ждет результата другой асинхронной функции (корутины). Это позволяет другим корутинам выполняться, пока текущая ждет.
Синтаксис
# Основной синтаксис
async def main():
result = await some_coroutine()
return result
# await можно использовать только в async функциях
async def fetch_data():
response = await asyncio.sleep(1) # Ждет 1 секунду
return "data"
# Это ОШИБКА — await вне async функции
def sync_function():
result = await fetch_data() # SyntaxError!
Как работает await под капотом
1. Приостановка выполнения
import asyncio
async def task(name, delay):
print(f"{name} начал")
await asyncio.sleep(delay)
print(f"{name} закончил")
return f"Результат {name}"
async def main():
# Без await — запускает параллельно
result1 = await task("Task-1", 2) # Ждет 2 сек
result2 = await task("Task-2", 2) # Ждет еще 2 сек
# Всего 4 сек
print(result1) # Результат Task-1
print(result2) # Результат Task-2
asyncio.run(main())
2. Параллельное выполнение с asyncio.gather
import asyncio
async def task(name, delay):
print(f"{name} начал")
await asyncio.sleep(delay)
print(f"{name} закончил")
return f"Результат {name}"
async def main():
# Запускает ПАРАЛЛЕЛЬНО
results = await asyncio.gather(
task("Task-1", 2),
task("Task-2", 2),
task("Task-3", 2)
)
# Всего 2 сек (параллельно), не 6 сек
print(results)
asyncio.run(main())
Практические примеры
HTTP запросы
import aiohttp
import asyncio
async def fetch_url(session, url):
async with session.get(url) as response:
return await response.json()
async def fetch_multiple():
async with aiohttp.ClientSession() as session:
tasks = [
fetch_url(session, "https://api.example.com/users/1"),
fetch_url(session, "https://api.example.com/users/2"),
fetch_url(session, "https://api.example.com/users/3"),
]
# Выполняет все 3 запроса параллельно
results = await asyncio.gather(*tasks)
return results
asyncio.run(fetch_multiple())
FastAPI с await
from fastapi import FastAPI
import asyncio
import httpx
app = FastAPI()
@app.get("/data")
async def get_data():
# Неправильно — блокирует
response = requests.get("https://api.example.com/data")
# Правильно — асинхронно
async with httpx.AsyncClient() as client:
response = await client.get("https://api.example.com/data")
return response.json()
Database запросы
import asyncpg
import asyncio
async def get_users():
# Подключение к БД
conn = await asyncpg.connect(
"postgresql://user:password@localhost/db"
)
try:
# Ждем результата запроса
users = await conn.fetch('SELECT * FROM users')
return users
finally:
await conn.close()
result = asyncio.run(get_users())
Сравнение синхронного и асинхронного
Синхронный код (блокирующий)
import time
import requests
def sync_fetch():
start = time.time()
# Блокирует на 1 сек
response1 = requests.get("https://httpbin.org/delay/1")
# Блокирует еще на 1 сек
response2 = requests.get("https://httpbin.org/delay/1")
# Блокирует еще на 1 сек
response3 = requests.get("https://httpbin.org/delay/1")
elapsed = time.time() - start
print(f"Время: {elapsed:.2f}s") # ~3.0 сек
sync_fetch()
Асинхронный код (неблокирующий)
import asyncio
import httpx
import time
async def async_fetch():
start = time.time()
async with httpx.AsyncClient() as client:
tasks = [
client.get("https://httpbin.org/delay/1"),
client.get("https://httpbin.org/delay/1"),
client.get("https://httpbin.org/delay/1"),
]
# Выполняются параллельно
responses = await asyncio.gather(*tasks)
elapsed = time.time() - start
print(f"Время: {elapsed:.2f}s") # ~1.0 сек!
asyncio.run(async_fetch())
Обработка исключений
import asyncio
async def risky_operation():
await asyncio.sleep(1)
raise ValueError("Что-то пошло не так")
async def main():
try:
result = await risky_operation()
except ValueError as e:
print(f"Поймали ошибку: {e}")
asyncio.run(main())
Ключевые моменты
- await работает только в async функциях
- await приостанавливает текущую корутину, позволяя другим выполняться
- asyncio.gather() запускает несколько корутин параллельно
- Асинхронный код быстрее для I/O операций (сеть, БД, файлы)
- Синхронный код лучше для CPU-bound операций (вычисления)