首页 > 解决方案 > 使用 Python 进行异步和等待

问题描述

我之前在 C# 中使用过 async/await ,就像在这个问题中一样,但这是一个我需要不时去基础知识进行刷新的概念。

这次我在 Python 中工作,但是这个问题更多的是关于 Async Await 的概念而不是实现。

基本上我有一个服务器,我向它发送一个请求,这个服务器发送一个响应。如果我只有一次

async def send_and_get_response(self,request):
   self.remote_server.send_request(request)
   response= await self.remote_server.get_response()
   return response

那里没问题。

但是,假设我想向服务器发送的不是一个而是多个请求,并且我想等待响应。我不想在收到回复发送一个请求,而是一次发送。我也不想错过回复。

如果我错了,请纠正我,但 async/await 的本质是,如果我在 await之后放置代码,则该代码在等待完成之前不会被执行,对吗?

所以这不会做对吗?

   async def send_and_get_response(self,request1,request2):
       self.remote_server.send_request(request1)
       response1= await self.remote_server.get_response()
       self.remote_server.send_request(request2)
       response2= await self.remote_server.get_response()
       return [response1,response2]

我想在上述情况下, request2 只有response1 到达后才会发送,我错了吗?

那么该怎么办?我想像

 async def send_and_get_response(self,request1,request2):
       self.remote_server.send_request(request1)
       self.remote_server.send_request(request2)
       response1= await self.remote_server.get_response()
       response2= await self.remote_server.get_response()
       return [response1,response2]

但这不知何故感觉不对。如果 response1 在我等待它之前立即到达怎么办?如果 response2 比 response1 早到达怎么办?

那么这个怎么样:

async def send_and_get_response(self,request):
   self.remote_server.send_request(request)
   response= await self.remote_server.get_response()
   return response

response1=send_and_get_response(request1)
response2=send_and_get_response(request2)

这行得通吗?

我再说一遍,我想要完成的是向服务器发送两个(或更多)请求并等待所有请求的响应。它们可以以不同的顺序出现。

编辑

这个怎么样

    async def send_and_get_response(self,request):
       self.remote_server.send_request(request)
       response= await self.remote_server.get_response()
       return response
    
 results=  await asyncio.gather(
            send_and_get_response(request1),
            send_and_get_response(request2),
            send_and_get_response(request3),
        )

这行得通吗?如果是这样,我如何获得回复?

编辑 2

我检查了其他资源,我想知道如何进行以下工作

async def process_when_done(tasks):
    for res in asyncio.as_completed(tasks):
        print("Result %s" % await res)    
    
tasks2= [ send_and_get_response(request1),
        send_and_get_response(request2),
        send_and_get_response(request3)]   
    
process_when_done(tasks2)

在这种情况下,我试图在完成后立即处理每个进程

标签: pythonasynchronousasync-await

解决方案


我想在上述情况下, request2 只有在 response1 到达后才会发送,我错了吗?

你是对的。

但这不知何故感觉不对。如果 response1 在我等待它之前立即到达怎么办?如果 response2 比 response1 早到达怎么办?

可能是对的,因为您想等待所有响应(这意味着您实际上正在等待最长的响应)。如果您需要立即对响应执行某些操作,则可能不正确:

async def send_and_get_response(self,request1,request2):
    self.remote_server.send_request(request1)
    self.remote_server.send_request(request2)
    response1= await self.remote_server.get_response()
    # do something here with response1
    # if response2 arrives first, then we are wasting time.
    response2= await self.remote_server.get_response()
    # do something here with response2
    return [response1,response2]

这行得通吗?

不,send_and_get_response是一个异步函数,你需要await send_and_get_response,或者你什么都不做,但是如果你等待它,那么与第一个实现没有区别。


实际上,我们asyncio.gather在 Python 中用于此目的。


推荐阅读