【问题标题】:Asynchronous, Multiple HTTP requests in a While LoopWhile 循环中的异步、多个 HTTP 请求
【发布时间】:2021-11-07 22:16:50
【问题描述】:

下面的代码旨在在 while 循环 中发送多个 HTTP 请求异步,并取决于每个请求的响应(请求“X”总是返回“XXX”,“Y”总是返回“YYY”等等),做一些事情并睡眠为每个请求指定interval秒。


但是,它会引发错误...

RuntimeError: cannot reuse already awaited coroutine

谁能帮助我如何修复代码以实现预期的行为?

class Client:
    def __init__(self):
        pass

    async def run_forever(self, coro, interval):
        while True:
            res = await coro
            await self._onresponse(res, interval)

    async def _onresponse(self, res, interval):
        if res == "XXX":
            # ... do something with the resonse ...
            await asyncio.sleep(interval)
        if res == "YYY":
            # ... do something with the resonse ...
            await asyncio.sleep(interval)
        if res == "ZZZ":
            # ... do something with the resonse ...
            await asyncio.sleep(interval)


async def request(something):
    # ... HTTP request using aiohttp library ...
    return response


async def main():
    c = Client()
    await c.run_forever(request("X"), interval=1)
    await c.run_forever(request("Y"), interval=2)
    await c.run_forever(request("Z"), interval=3)
    # ... and more

【问题讨论】:

    标签: python asynchronous python-asyncio coroutine


    【解决方案1】:

    正如错误所说,您不能多次等待协程。不是将协程传递给run_forever,然后在循环中等待它,而是传递协程的参数并在循环的每次迭代中等待一个新的协程。

    class Client:
        async def run_forever(self, value, interval):
            while True:
                res = await rqequest(value)
                await self._response(response, interval)
    

    您还需要更改等待run_forever 的方式。 await 是阻塞的,所以当你等待一个无限循环的东西时,你永远不会到达下一行。相反,您希望一次收集多个协程。

    async def main():
        c = Client()
        await asyncio.gather(
            c.run_forever("X", interval=1),
            c.run_forever("Y", interval=2),
            c.run_forever("Z", interval=3),
        )
    

    【讨论】:

    • 谢谢。你知道为什么不允许我们多次等待一个协程吗?
    • 协程总是只运行一次。在允许多次等待的语言中,您的代码仍然无法工作,因为 request 只会被调用三次。
    猜你喜欢
    • 2018-04-10
    • 2023-03-06
    • 2017-11-22
    • 2013-04-10
    • 2020-02-18
    • 2013-11-23
    • 1970-01-01
    • 2011-01-08
    相关资源
    最近更新 更多