While 循环中的异步、多个 HTTP 请求

Asynchronous, Multiple HTTP requests in a While Loop

下面的代码旨在在 while 循环 中发送多个 HTTP 请求异步 ,并根据每个请求的响应(请求“X”总是returns“XXX”,“Y”总是returns“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

如错误所述,您不能多次等待协程。与其将协程传递到 run_forever 然后在循环中等待它,不如传递协程的参数并在循环的每次迭代中等待新的协程。

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

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

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),
    )