【发布时间】:2021-04-02 08:35:07
【问题描述】:
我有一个发布两个请求的 fastAPI 应用程序,其中一个请求更长(如果有帮助,它们是 Elasticsearch 查询,我正在使用已经返回协程的 AsyncElasticsearch 模块)。这是我的尝试:
class my_module:
search_object = AsyncElasticsearch(url, port)
async def do_things(self):
resp1 = await search_object.search() #the longer one
print(check_resp1)
resp2 = await search_object.search() #the shorter one
print(check_resp2)
process(resp2)
process(resp1)
do_synchronous_things()
return thing
app = FastAPI()
@app.post("/")
async def service(user_input):
result = await my_module.do_things()
return results
我观察到的不是等待resp1,当它到达check_resp1 时,它已经是一个完整的响应,就好像我根本没有使用异步一样。
我是 python async 的新手,我知道我的代码不会工作,但我不知道如何修复它。据我了解,当解释器看到await 时,它会启动函数然后继续前进,在这种情况下应该立即发布下一个请求。我如何让它做到这一点?
【问题讨论】:
-
我认为你在这里搞混了一些东西。当您使用
await时,字面意思 的意思是“停在这里,等到结果到来”。所以很自然,await search_object.search()之后的一行回复是完全可用的。如果您不想等待,请不要使用await。 -
使用
await和使用同步函数调用的唯一区别是await只暂停当前函数,而不是整个世界。您的程序可以在任意数量的函数等待某事时执行其他操作。但从函数的角度来看,result = await asynchronous_thing()和result = synchronous_thing()的行为完全相同。 -
@Tomalak 谢谢!所以我确实理解错了。就像你说的,如果
await暂停“当前函数”,是否意味着每个 I/O 绑定的任务都需要写在一个单独的函数中?它又是如何回归的呢?我想这是更低级别的,但我可以想当然地认为它会在完成后发生吗? -
您可以通过使用
await对每个任务执行一次 (a = await func_a(); b = await func_b()) 顺序执行任务,也可以并行执行任务,将任务背靠背拍摄并为组使用一次await(@ 987654337@),其中asyncio.gather()是一个助手,它为您提供一个等待的任务,一旦所有参数都完成,该任务就会完成。
标签: python elasticsearch python-asyncio fastapi