【问题标题】:async and await with Python使用 Python 进行异步和等待
【发布时间】:2020-09-11 14:22:30
【问题描述】:

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

这次我在 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 的本质是,如果我将代码 after 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

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

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)

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

【问题讨论】:

    标签: python asynchronous async-await


    【解决方案1】:

    我想在上述情况下,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,否则你什么都不做,但是如果你等待它,那么和第一个实现没有区别。


    实际上,我们在 Python 中为此使用了asyncio.gather

    【讨论】:

    • 我明白了,所以最后一个不起作用。我现在看到了。 ;(我会检查你的链接,但你知道如何做我想做的事吗?
    • 您的第二个实现确实有效。或者您可以按照链接使用更pythonic的方式。
    • 我又添加了一次尝试asyncio.gather。你能看一下吗?
    • 是的,有道理。
    • "结果值的顺序对应于 aws 中等待的顺序。"请参阅文档。
    猜你喜欢
    • 1970-01-01
    • 2023-03-30
    • 2019-02-10
    • 2019-07-29
    • 2015-07-27
    • 2013-08-01
    • 1970-01-01
    • 2017-05-11
    相关资源
    最近更新 更多