如何使用 asyncio.gather 立即解析响应?

how to parse response immediately with asyncio.gather?

async def main():
    uuids = await get_uuids_from_text_file()
    tasks = []
    # create a task for each uuid
    # and add it to the list of tasks
    for uuid in uuids:
        task = asyncio.create_task(make_hypixel_request(uuid))
        tasks.append(task)
    # wait for all the tasks to finish
    responses = await asyncio.gather(*tasks)
    # run the functions to process the data
    for response in responses:
        print(response['success'])
        data2 = await anti_sniper_request(response)
        await store_data_in_json_file(response, data2)
        await compare_stats(response)

# loop the main function
async def main_loop():
    for _ in itertools.repeat([]):
        await main()


# run the loop
loop = asyncio.get_event_loop()
loop.run_until_complete(main_loop())
loop.close()

基本上这是我的代码函数有非常清晰和解释性的名称 make_hypixel_requests 部分我没有问题,请求立即并行执行, 问题是,当“响应中的响应”变得很慢时?我如何立即获得响应并快速循环?我会尝试附上 gif。

基本上是这个问题:

您可以使用asyncio.wait和return至少完成一个任务,然后继续等待待处理的任务。 asyncio.wait return 一个包含两组的元组,第一个包含已完成的任务,第二个包含尚未完成的任务。您可以调用已完成任务的 result 方法并获取其 return 值。

async def main():
    uuids = await get_uuids_from_text_file()
    tasks = []
    # create a task for each uuid
    # and add it to the list of tasks
    for uuid in uuids:
        task = asyncio.create_task(make_hypixel_request(uuid))
        tasks.append(task)
    # wait for all the tasks to finish
    while tasks:
        done_tasks, tasks = await asyncio.wait(tasks, return_when=asyncio.FIRST_COMPLETED)
        for done in done_tasks:
            response = done.result()
            print(response['success'])
            data2 = await anti_sniper_request(response)
            await store_data_in_json_file(response, data2)
            await compare_stats(response)

原因是因为在等待 所有 对 return 的响应后,你在循环中而不是异步地处理它们,因为 none请求似乎相互依赖,等待它们全部完成再处理它们没有意义,处理这个问题的最好方法是将请求和处理结合起来,例如

async def request_and_process(uuid):
    response = await make_hypixel_request(uuid)
    print(response['success'])
    compare_stats_task = asyncio.create_task(compare_stats(response))
    data2 = await anti_sniper_request(response)
    await asyncio.gather(store_data_in_json_file(response, data2), compare_stats_task)

async def main():
    while True:
        uuids = await get_uuids_from_text_file()
        await asyncio.gather(*map(request_and_process, uuids))

asyncio.run(main())