asyncio相关 - 按key区分任务 ¶
作者:KK
发表日期:2020.02.15
应用场景 ¶
很多时候我们需要给多个异步任务打一些标记,在执行完后,通过这些标记把它们的值取出来进行判断。
示例代码 ¶
下面代码最终还是通过async.gather
来执行任务,但是在执行之前先将 tasks 打包成了一个带有标识符的列表。关于这个解决方案我是在 Stack Overflow 上请教来的,大家都研究了直到 python3.7 官方是没有直接的解决方案的,3.8开始有没有就不清楚了。
import asyncio, aiohttp
async def markCallback(key, callback):
"""用一个key把一个任务标记起来
"""
result = None
try:
result = await callback
except BaseException as e:
result = e
return key, result
async def gatherDict(tasks: dict, throwException: bool = True):
"""执行字典形式的任务
"""
markedCallbacks = (markCallback(key, callback) for key, callback in tasks.items())
parallelResult = await asyncio.gather(*markedCallbacks, loop = None, return_exceptions = True)
resultByKeys = {}
for resultSet in parallelResult:
taskName, taskResult = resultSet
if isinstance(taskResult, BaseException):
if throwException:
raise taskResult
resultByKeys[taskName] = taskResult
return resultByKeys
async def getHtml(url):
async with aiohttp.ClientSession() as httpSession:
async with httpSession.get(url) as response:
return await response.text()
async def main():
tasks = {
'html1': getHtml('http://www.kkh86.com/it'),
'html2': getHtml('http://www.kkh86.com/it/python'),
}
result = await gatherDict(tasks) #开始执行,注意这里!!!! 不是 *tasks ,是直接把这个 dict 传进去
print(
'请求1的HTML',
result['html1'][:100],
'\n\n\n=====================分割线==============================\n\n\n',
'请求2的HTML',
result['html2'][:100]
)
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
loop.close()