Для каждой задачи, состоящей из пары запросов, гарантированно возвращается запрос A перед отправкой запроса B?
Да, преимущество шаблона асинхронности / ожидания состоит в том, что выне задавайте себе этот вопрос, последовательные строки кода всегда будут выполняться последовательно (, но не обязательно последовательно ). Здесь ваша функция request_chain
гарантирует, что request_A
всегда будет выполняться до request_B
.
, пока ожидается запрос A, запрос B может выполнить
, чтоне произойдет, это в основном то, что означает wait
: дождитесь, пока запрос A не вернется, прежде чем идти дальше . Другими словами, wait
не влияет на порядок выполнения. Он просто передает элемент управления , поэтому время ожидания может использовать кто-то еще (в вашем случае любой код из другой (A, B) пары запросов).
Единственный код, который будет выполняться параллельно, - это тот, который вы запланируете самостоятельно (в этом случае, используя asyncio.gather
, запланируйте несколько (A, B) пар для параллельного выполнения),
Я понимаю, что могу выполнить все вызовы Request A в пакете, а затем выполнить все вызовы Request B в пакете, но по причинам, характерным для моего варианта использования, мне нужно запустить пакет всех...
В этом конкретном случае, даже если вы можете запустить партию из A , то, по-моему, партию из B Ваше решение будет лучше, так как оно упрощает и подчеркивает связь между A и B .
Вот пример кода, который вы можете запустить, чтобы попробовать что-тоout (он делает то же самое, что вы делаете здесь с общедоступным математическим API), он просто вычисляет «x * 2 + 2» за два шага, сначала «* 2» (эквивалент запроса A ),затем «+2» (эквивалент запроса B ):
MATH_API_URL = "http://api.mathjs.org/v4"
from aiohttp import ClientSession
import asyncio
async def maths(session, url, expression):
params = {"expr" : expression}
print(f"\t> computing {expression}")
async with session.get(url, params=params) as response:
result = await response.text()
print(f"\t< {expression} = {result}")
return result
async def twice(session, x):
return await maths(session, MATH_API_URL, f"2 * {x}")
async def plus_two(session, x):
return await maths(session, MATH_API_URL, f"2 + {x}")
async def twice_plus_two(session, x):
twice_x = await twice(session, x)
return await plus_two(session, twice_x)
async def main(inputs):
async with ClientSession() as session:
return await asyncio.gather(*(twice_plus_two(session, x) for x in inputs))
inputs = list(range(3))
print([x*2+2 for x in inputs])
print(asyncio.run(main(inputs)))
Этот код выводит порядок, в котором запланированы запросы:
[2, 4, 6]
> computing 2 * 0
> computing 2 * 1
> computing 2 * 2
< 2 * 1 = 2
> computing 2 + 2
< 2 * 0 = 0
> computing 2 + 0
< 2 * 2 = 4
> computing 2 + 4
< 2 + 2 = 4
< 2 + 4 = 6
< 2 + 0 = 2
['2', '4', '6']
Посмотрите, как«+2» запланированы, как только вернется «* 2».