我很惭愧地承认,我已经使用python的asyncio很长一段时间了,但并没有真正理解它是如何工作的,现在我陷入了困境。在伪代码中,我当前的程序是这样的:
async def api_function1(parameters):
result = await asyncio.gather(*[some_other_thing(p) for p in parameters])
async def api_function2(parameters):
result = await asyncio.gather(*[some_other_thing2(p) for p in parameters])
def a(initial_parameters):
output = []
data = asyncio.run(api_function1(initial_parameters))
output.append(data)
while True:
data = asyncio.run(api_function1(get_parameters_from_data(data)))
output.append(data)
if some _condition is True:
break
return output
def b(initial_parameters):
output = []
data = asyncio.run(api_function2(initial_parameters))
output.append(data)
while True:
data = asyncio.run(api_function2(get_parameters_from_data(data)))
output.append(data)
if some condition is True:
break
return output
a()和B()从两个不同的REST API端点获取数据,每个端点都有自己的速率限制和细微差别。我希望同时运行a()和b()。
构造程序使a()和b()同时运行的最好/最简单的方法是什么?
我尝试让a()和B()都是异步方法,并尝试同时等待它们,例如
async a(initial_parameters):
...
async b(initial_parameters):
...
A = await a(initial_parameters)
B = await b(initial_parameters)
但它不起作用,所以根据文档,我猜我可能需要手动获取event_loop并将其作为参数传递给a()和b(),a()和b()将其传递给api_function2()和api_function2(),然后在两个任务都完成时手动关闭它,但不确定我是否走对了路或如何操作。
如果你有一个更好的设计模式,也可以打开它
1条答案
按热度按时间kknvjkwl1#
没有理由不能嵌套对asyncio. gather的调用,如果想同时运行a()和B(),必须使它们都成为协程,并且不能asyncio.run在其中任何一个中使用www.example.com()。因为这是一个阻塞调用-它在参数完成之前不会返回。您需要替换a()和b()中对asyncio.run()的所有调用用wait表达式。你会得到如下的结果:
这仍然是伪代码。
我给出了两种可能的编写main的方法(),一个使用
asyncio.gather
,另一个使用对asyncio.create_task的两次调用。这两个版本都创建了两个同时运行的任务,但后一个版本不需要像gather
那样将所有任务收集在一个位置并同时启动它们。如果gather
像这里一样满足您的要求,它更方便。最后,调用
asyncio.run
启动程序。文档建议每个程序只调用一次asyncio.run
。这两个API函数应该返回一些东西,而不是设置一个局部变量。
在asyncio中,关键的概念是任务。任务相互协作以提供同步执行。Asyncio.gather实际上在引擎盖下创建任务,即使你通常传递给它一个协程列表。这就是它并行运行事情的方式。