我有一个脚本可以针对类中的API运行并行请求。但是,我得到的结果基本上是一项任务,而不是实际结果。有什么原因吗?
我模仿了https://pawelmhm.github.io/asyncio/python/aiohttp/2016/04/22/asyncio-aiohttp.html上修改后的客户端代码。
import asyncio
from aiohttp import ClientSession
class Requestor:
async def _async_request(self, url, session, sema_sz=10):
sema = asyncio.Semaphore(sema_sz)
async with sema:
async with session.get(url) as response:
req = await response.json()
return req
async def _async_chunk_request(self, url, chunks, headers=None, sema_sz=10):
async with ClientSession(headers=headers) as session:
futures = [asyncio.ensure_future(self._async_request(url.format(chunk), session, sema_sz)) for chunk in chunks]
responses = asyncio.gather(*futures)
await responses
def get_request(self, url, chunks):
loop = asyncio.get_event_loop()
bulk_req = asyncio.ensure_future(self._async_chunk_request(url, chunks))
loop.run_until_complete(bulk_req)
return bulk_req
bulk_req实际上是一个Task变量,而不是结果,并在PyCharm Task finished coro=<Requestor._async_chunk_request() done, defined at ...
当我调试时,我看到req
具有完整而正确的响应值,因此没有问题。我觉得这与期货的实际收集有关吗?
答案 0 :(得分:1)
您的_chunk_request
不返回任何内容。
async def _chunk_request(...):
...
...
await responses
我制作了一个玩具示例,试图模仿您的过程。如果像您一样结束 _chunk_request
,我将得到相同的结果-完成的任务没有结果。更改_chunk_request
以返回某物修复了该问题:
async def _chunk_request(...):
...
...
return await responses
如果仅需要任务的返回值,则get_request
应该返回loop.run_until_complete()
调用的结果。
我的玩具示例
import asyncio
import random
from pprint import pprint
async def response(n):
asyncio.sleep(random.choice([1,3,5]))
return f'i am {n}'
async def _request(n):
req = await response(n)
#print(req)
return req
async def _chunk_request(chunks):
futures = [asyncio.ensure_future(_request(chunk)) for chunk in chunks]
#pprint(futures)
responses = asyncio.gather(*futures, return_exceptions=True)
#pprint(responses)
return await responses
def get_request(chunks):
loop = asyncio.get_event_loop()
bulk_req = asyncio.ensure_future(_chunk_request(chunks))
return loop.run_until_complete(bulk_req)
In [7]: result = get_request(range(1,6))
In [8]: print(result)
['i am 1', 'i am 2', 'i am 3', 'i am 4', 'i am 5']