如何在没有等待的情况下调用异步函数?

Posted

技术标签:

【中文标题】如何在没有等待的情况下调用异步函数?【英文标题】:How can I call an async function without await? 【发布时间】:2017-06-19 12:32:54 【问题描述】:

我在 aiohttp 应用程序中有一个控制器操作。

async def handler_message(request):

    try:
        content = await request.json()
        perform_message(x,y,z)
    except (RuntimeError):
        print("error in perform fb message")
    finally:
        return web.Response(text="Done")

perform_message 是异步函数。现在,当我调用操作时,我希望我的操作尽快返回并将perform_message 放入事件循环中。

这样,perform_message 不会被执行

【问题讨论】:

【参考方案1】:

一种方法是使用create_task 函数:

import asyncio

async def handler_message(request):
    ...
    loop = asyncio.get_event_loop()
    loop.create_task(perform_message(x,y,z))
    ...

【讨论】:

是的,但是直到等待才开始,对吧?如果你想创建它,启动它,做其他事情然后等待它怎么办(它可能已经完成,如果没有,它会阻塞直到完成) @Jeppe 不,create_task 将尽快启动它。我鼓励您对其进行测试(您根本不必等待结果)。 @HossamAl-Dokkani 老兄,你在评论之前检查一下如何?它确实启动了任务。你不必等待它。期间。 @freakish 但我不想永远运行它我需要我的函数终止并用 HttpResponse 响应,我不想await 得到结果。 @HossamAl-Dokkani 听着,没有办法在未运行的循环上运行异步函数。您必须开始循环。您可以通过loop.run_until_complete(coro)loop.run_forever() 进行操作。请参阅:docs.python.org/3/library/… 在您的情况下,您似乎正在寻找第一个选项。【参考方案2】:

其他方法是使用ensure_future 函数:

import asyncio

async def handler_message(request):
...
loop = asyncio.get_event_loop()
loop.ensure_future(perform_message(x,y,z))
...

【讨论】:

这将引发AttributeError: '_UnixSelectorEventLoop' object has no attribute 'ensure_future'ensure_futureasyncio 模块的函数,而不是事件循环的方法。如果您只处理协程,它也与loop.create_task 基本相同。

以上是关于如何在没有等待的情况下调用异步函数?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用回调在任何函数中调用异步等待方法

在没有等待 #2 的情况下调用异步方法

ES7 - 如何停止(剪切)异步/等待链接

如何在没有 IdlingResource 的情况下在 Espresso 中等待异步任务

如何在异步函数中处理多个等待

如何在同步函数中等待 JavaScript 中的异步调用?