我一直在尝试各种方法,以便能够在另一个异步循环中使用异步循环。大多数时候我的测试都会以错误结束,例如:
运行时错误:此事件循环已在运行
下面的示例代码只是我开始的基本测试,因此您可以了解我正在尝试执行的操作的基础知识。这次测试后我尝试了很多东西,这太令人困惑了,所以我想在寻求帮助时应该保持简单。如果有人能指出我正确的方向,那就太好了。谢谢您的宝贵时间!
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 的目的。因此,asyncio 事件循环不是递归的,并且不需要递归地运行它们。 (有关详细信息,请参阅此问题。)不要创建内部事件循环,而是在现有事件循环上创建
await
任务。在您的情况下,删除
sub_run
并简单地替换其用法:
images = sub_run(other_data)
与:
images = await sub_build(other_data)
它会工作得很好,运行子协程,并且在内部协程完成之前不会继续执行外部协程,正如您可能从同步代码中预期的那样。