То, что вы видите, является недостатком использования сопрограмм в этом случае. Потому что, несмотря на то, что запросы не блокируют, они на самом деле не асинхронны
Вы можете использовать gen.WaitIterator
для одновременной отправки всех запросов, действительно асинхронно.
Как сказано в документации:
Если вам нужно получить результат каждого будущего как можно скорее, или если вам нужен результат некоторых фьючерсов, даже если другие выдают ошибки, вы можете использовать WaitIterator
.
Отлично подходит для вашего случая использования.
gen.WaitIterator
принимает произвольное количество фьючерсов в качестве аргументов и возвращает фьючерсы по мере их завершения.
Однако, чтобы это работало, вам нужно переместить петлю for
в сопрограмму go
. Пример: * +1022 *
from tornado import gen
async def go(r):
client = AsyncHTTPClient()
futures = []
for _ in range(r):
print('go----------')
request = HTTPRequest(url='http://127.0.0.1:8001/api', method='GET',)
futures.append(client.fetch(request))
async for result in gen.WaitIterator(*futures):
print(result.code, result.body)
Как примечание, есть еще один способ сделать это - использовать обратные вызовы. Однако WaitIterator
должно быть предпочтительнее обратных вызовов. Я написал сообщение в блоге об этом некоторое время назад, если вам интересно.