简体   繁体   English

将函数列表传递给 asyncio.gather()

[英]Passing in a list of functions to asyncio.gather()

from aiohttp import ClientSession
import asyncio
import threading
import time     

 class Query():

    def execute_async(self):
    asyncio.run(self.call_requests())

    async def call_requests(self):
        self.api_request_list = []

        self.PROMETHEUS_URL = "http://www.randomnumberapi.com/api/v1.0/random?min=100&max=1000&count=1"

        self.api_request_list.append(self.api_request(self.PROMETHEUS_URL, 1))
        self.api_request_list.append(self.api_request(self.PROMETHEUS_URL, 1))
        self.api_request_list.append(self.api_request(self.PROMETHEUS_URL, 1))

        while True:
            timer_start = time.perf_counter()

            await asyncio.gather(*self.api_request_list)

            timer_stop = time.perf_counter()
            print(f"Performed all requests in... {timer_stop - timer_start:0.4f} seconds")

    async def api_request(self, query, sleep_duration):
        await asyncio.sleep(sleep_duration)
        async with ClientSession() as session:
            async with session.get(self.PROMETHEUS_URL) as response:
            response = await response.text()
            random_int = int(response[2])
            print('Request response... {0}'.format(random_int))

if __name__ == '__main__':
    query = Query()

The api_request_list should hold a list of functions. api_request_list 应该包含一个函数列表。 This list of functions should be passed into asyncio.gather.这个函数列表应该传递给 asyncio.gather。

I am currently getting the following error message:我目前收到以下错误消息:

RuntimeError: cannot reuse already awaited coroutine

That's not a list of functions.这不是功能列表。 asyncio.gather doesn't take a list of functions. asyncio.gather不接受函数列表。

What you have there is a list of coroutine objects .你所拥有的是协程对象列表。 Calling an async function produces a coroutine object, which holds the state of the async function call's execution.调用async function 会产生协程 object,它保存异步 function 调用执行的 state。

When you pass the list to asyncio.gather a second time, all the coroutines are already finished.当您第二次将列表传递给asyncio.gather时,所有协程都已完成。 You're telling asyncio.gather "run these coroutines", and asyncio.gather is telling you "I can't do that - they already ran".你告诉asyncio.gather “运行这些协同程序”,而asyncio.gather告诉你“我不能那样做——它们已经运行了”。

If you want to run an async function again, you need to call it again.如果你想再次运行 async function,你需要再次调用它。 You can't keep using the old coroutine objects.您不能继续使用旧的协程对象。 That means you need to populate the list inside the loop:这意味着您需要在循环内填充列表:

while True:
    api_request_list = [
        self.api_request(self.PROMETHEUS_URL, 1),
        self.api_request(self.PROMETHEUS_URL, 1),
        self.api_request(self.PROMETHEUS_URL, 1),
    ]

    timer_start = time.perf_counter()

    await asyncio.gather(*api_request_list)

    timer_stop = time.perf_counter()
    print(f"Performed all requests in... {timer_stop - timer_start:0.4f} seconds")

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM