我们如何在需要协程的地方调用普通函数?
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
,但是将函数转换为协程的面向未来的方法是什么?以上是关于我们如何在需要协程的地方调用普通函数?的主要内容,如果未能解决你的问题,请参考以下文章
Kotlin 协程协程的挂起和恢复 ① ( 协程的挂起和恢复概念 | 协程的 suspend 挂起函数 )