我一直在尝试各种方法,以便能够在另一个asyncio循环中使用asyncio循环。大多数情况下,我的测试以错误告终,例如:
RuntimeError:此事件循环已在运行
下面的示例代码只是我开始的基本测试,因此您可以看到我正在尝试执行的基本操作。在这次测试之后,我尝试了很多东西,只是太混乱了,所以我想在寻求帮助时应该保持简单。如果有人能给我指出正确的方向,那就太好了。感谢您抽出时间!
import asyncio async def fetch(data): message = 'Hey {}!'.format(data) other_data = ['image_a.com', 'image_b.com', 'image_c.com'] images = sub_run(other_data) return {'message' : message, 'images' : images} async def bound(sem, data): async with sem: r = await fetch(data) return r async def build(dataset): tasks = [] sem = asyncio.Semaphore(400) for data in dataset: task = asyncio.ensure_future(bound(sem, data)) tasks.append(task) r = await asyncio.gather(*tasks) return r def run(dataset): loop = asyncio.get_event_loop() future = asyncio.ensure_future(build(dataset)) responses = loop.run_until_complete(future) loop.close() return responses async def sub_fetch(data): image = 'https://{}'.format(data) return image async def sub_bound(sem, data): async with sem: r = await sub_fetch(data) return r async def sub_build(dataset): tasks = [] sem = asyncio.Semaphore(400) for data in dataset: task = asyncio.ensure_future(sub_bound(sem, data)) tasks.append(task) r = await asyncio.gather(*tasks) return r def sub_run(dataset): loop = asyncio.get_event_loop() future = asyncio.ensure_future(sub_build(dataset)) responses = loop.run_until_complete(future) loop.close() return responses if __name__ == '__main__': dataset = ['Joe', 'Bob', 'Zoe', 'Howard'] responses = run(dataset) print (responses)
跑步 loop.run_until_compete 运行中的事件循环内部会阻塞外部循环,因此无法达到使用asyncio的目的。因此,异步IO事件循环不是递归的,不需要递归地运行它们。而不是创建内部事件循环, await 现有任务上的任务。
loop.run_until_compete
await
在您的情况下,请删除 sub_run 并简单地替换其用法:
sub_run
images = sub_run(other_data)
使用:
images = await sub_build(other_data)
它将很好地工作,运行子协同路由,在内部协同路由完成之前不继续执行外部协同路由,就像您在同步代码中所期望的那样。