Python 3.10 asyncio.ather()显示异常警告:没有当前事件循环

2022-03-25 00:00:00 python python-asyncio python-3.10

问题描述

我有一个Django应用程序,在它的一个视图中,我使用Asyncio向外部组件发出一些并发请求。

想法是这样的:

import asyncio


async def do_request(project):
    result = ...

    return result

def aggregate_results(projects: list):
    loop = asyncio.new_event_loop()

    asyncio.set_event_loop(loop)

    results = loop.run_until_complete(
        asyncio.gather(*(do_request(project) for project in projects))
    )

    loop.close()

    return zip(projects, results)

嗯,当我运行测试时,我得到以下行的DeprecationWarning: There is no current event loop

        asyncio.gather(*(do_request(project) for project in projects))

我应该如何解释此警告,需要更改哪些内容才能消除它?谢谢!


解决方案

根据documentation,这是因为您调用gather时没有事件循环运行。

自3.10版起不推荐使用:如果未提供位置参数或并非所有位置参数都是类Future对象并且没有正在运行的事件循环,则会发出弃用警告。

您可能已经注意到,您的代码可以工作。它将继续工作,只要您使用3.10,您就可以忽略弃用警告。不过,在将来的某个时候,这可能会更改为运行时错误。

请您稍等片刻,the recommended way to run an event loop is with run,不是loop.run_until_complete

def aggregate_results(projects: list):
    results = asyncio.run(asyncio.gather(*(do_request(project) for project in projects)))
    return zip(projects, results)
但是,这实际上不会起作用。相反,您将获得一个异常

ValueError: a coroutine was expected, got <_GatheringFuture pending>

修复方法是改为等待来自另一个协程的gather

async def get_project_results(projects: list):
    results = await asyncio.gather(*(do_request(project) for project in projects))
    return results

def aggregate_results(projects: list):
    results = asyncio.run(get_project_results(projects))
    return zip(projects, results)

(您也可以将get_project_results与您的aggregate_results版本一起使用。)

相关文章