Параллельное выполнение запросов

У меня есть 2 асинхронных запроса. Я хочу, чтобы они выполнялись в параллель друг другу. Поясню.Я хочу, чтобы к моменту, когда я сделаю await resp_a, и fetch(a), и fetch(b) уже скорее всего отработали и мне не потребуется ожидать ответа от сервера?

resp_a = fetch(a) 
resp_b = fetch(b) 
time.sleep(long_time)
await resp_a
await resp_b

В реальности, после выполнения fetch(a), запроса к серверу не происходит. Происходит он лишь в момент времени await resp_a. По крайней мере, так происходит в дебаггере.


Есть 2 запроса к разным сервисам. Считаем, что они достаточно тяжёлые. Хочется, не дожидаться их ответа, а выполнять их в параллель.

async def fetch():
    print('2')
    ...

print('1')
resp_a = fetch(a)  # Тяжёлый запрос 1
print('3')
resp_b = fetch(b)  # Тяжёлый запрос 2 
time.sleep(long_time)  # Тяжёлая обработка. Где-то здесь, в параллель с этой тяжёлой обработкой запрос 1 обработался и запрос 2 обработался.
await resp_a  
await resp_b

Как я говорил выше, если выполнять в дебаггере, я получу:

1 2 3

Без

1 3 2


Ответы (1 шт):

Автор решения: eri
resp_a = fetch(a) 
resp_b = fetch(b) 

Не выполняет запросов, а только создает структуру асинхронных вызовов. awaitable объект.

Начать его выполнять его надо присоединить к loop. Слово await делает из awaitable future b выполняет все запланированные future.

Чтоб выполнить их параллельно следует использовать asyncio.gather или asyncio.wait, иногда случае enshure_future

gather - выполняет оба запроса конкурентно

result_a, result_b = await asyncio.gather(resp_a,resp_b) # выполняет запросы

wait - запускает оба запроса, возвращает первый или все

done, pending = await asyncio.wait([resp_a,resp_b],return_when=FIRST_COMPLETED)

first = await done
done, pending = await asyncio.wait(pending,return_when=FIRST_COMPLETED)
second = await done

asyncio.ensure_future - запускает запрос

resp_a = asyncio.ensure_future(fetch(a))
resp_b = asyncio.ensure_future(fetch(b))

Запрос запущен, но ещё не отправлен.

time.sleep(long_time)

всё ещё не запущен, time.sleep блокирует выполнение запросов

await asyncio.sleep(long_time)

вот тут запустятся все три: resp_b,resp_a, sleep и ждем sleep

await resp_a
await resp_b

Дожидаемся resp_a, а потом resp_b.

→ Ссылка