Asyncio 和 aiohttp 返回任务而不是结果
Asyncio and aiohttp returning task instead of results
我有一个脚本可以 运行 针对 class 中的 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 实际上是一个任务变量而不是结果,并在 PyCharm、Task finished coro=<Requestor._async_chunk_request() done, defined at ...
中显示
当我调试时,我发现 req
具有完整且正确的响应值,因此没有问题。感觉跟实际聚集期货有关系?
你的 _chunk_request
没有 return 任何东西。
async def _chunk_request(...):
...
...
await responses
我制作了一个 玩具 示例,试图模仿您的过程。如果我像您一样 ended _chunk_request
,我会得到相同的结果 - 完成的任务没有结果。将 _chunk_request
更改为 return something 修复了它:
async def _chunk_request(...):
...
...
return await responses
如果您只需要来自任务的 return 值,get_request
应该 return 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']
我有一个脚本可以 运行 针对 class 中的 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 实际上是一个任务变量而不是结果,并在 PyCharm、Task finished coro=<Requestor._async_chunk_request() done, defined at ...
当我调试时,我发现 req
具有完整且正确的响应值,因此没有问题。感觉跟实际聚集期货有关系?
你的 _chunk_request
没有 return 任何东西。
async def _chunk_request(...):
...
...
await responses
我制作了一个 玩具 示例,试图模仿您的过程。如果我像您一样 ended _chunk_request
,我会得到相同的结果 - 完成的任务没有结果。将 _chunk_request
更改为 return something 修复了它:
async def _chunk_request(...):
...
...
return await responses
如果您只需要来自任务的 return 值,get_request
应该 return 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']