我们如何在需要协程的地方调用普通函数?

Posted

技术标签:

【中文标题】我们如何在需要协程的地方调用普通函数?【英文标题】:How do we call a normal function where a coroutine is expected? 【发布时间】:2016-07-24 23:12:45 【问题描述】:

考虑一个调用另一个协程的协程:

async def foo(bar):
     result = await bar()
     return result

如果bar 是协程,这会很好。 如果bar 是一个正常功能,我需要做什么(即我需要用什么包装对bar 的调用)以便此代码执行正确的操作?

async def 定义一个协程是完全可能的,即使它从不做任何异步操作(即从不使用await)。 但是,问题询问如何在foo 的代码中包装/修改/调用常规函数bar,以便可以等待bar

【问题讨论】:

【参考方案1】:

如果需要,只需使用 asyncio.coroutine 包装您的同步函数:

if not asyncio.iscoroutinefunction(bar):
    bar = asyncio.coroutine(bar)

由于重新包装协程是安全的,所以实际上不需要协程功能测试:

async_bar = asyncio.coroutine(sync_or_async_bar)

因此,您的代码可以重写如下:

async def foo(bar):
     return await asyncio.coroutine(bar)()

【讨论】:

这似乎有效。请注意,有趣的是,asyncio.coroutine(normal_function)() 是一个生成器,而 a_coroutine_function() 是一个协程。 有什么方法可以将返回的生成器对象视为任务对象,例如调用Task.done() 并查看它是否仍在运行? Deprecated since version 3.8, will be removed in version 3.10。文档说改用async def,但是将函数转换为协程的面向未来的方法是什么?

以上是关于我们如何在需要协程的地方调用普通函数?的主要内容,如果未能解决你的问题,请参考以下文章

unity如何停止不用字符串方式开启协程的方法

深潜Koltin协程:协程构建器

Kotlin 协程协程的挂起和恢复 ① ( 协程的挂起和恢复概念 | 协程的 suspend 挂起函数 )

Kotlin 协程协程的挂起和恢复 ① ( 协程的挂起和恢复概念 | 协程的 suspend 挂起函数 )

Golang教程:goroutine协程

3.协程-挂起函数