仔细阅读AsyncIO
和文章中的许多文档后,我仍然找不到答案: 异步运行一个函数(不使用线程),并确保该函数调用此异步函数继续执行。
伪代码-
async def functionAsync(p):
#...
#perform intensive calculations
#...
print ("Async loop done")
def functionNormal():
p = ""
functionA(p)
return ("Main loop ended")
print ("Start Code")
print functionNormal()
预期输出:
Start code
Main loop ended
Async loop done
搜索了使用loop.run_until_complete
的示例,但由于它实际上是阻塞的,因此不会返回functionNormal()
的打印值。
答案 0 :(得分:0)
asyncio
不能在不使用线程的情况下“在后台”运行任意代码。正如{strong> user4815162342 所指出的,asyncio
您运行的事件循环会阻塞主线程并管理协程的执行。
如果要使用asyncio
并加以利用,则应重写所有使用协程的函数,直到主函数-程序入口点为止都是协程。该主要协程通常传递给run_until_complete
。 little post更加详细地揭示了这一主题。
由于您对Flask感兴趣,因此请看一下Quart:这是一个Web框架,它试图以asyncio
的形式来实现Flask API(尽可能多地)。该项目存在的原因是因为纯Flask与asyncio
不兼容。 Quart被编写为兼容。
如果您希望使用纯Flask,但又需要异步处理,请查看gevent。通过猴子补丁,它可以使您的代码异步。尽管此解决方案有其自身的问题(创建asyncio
的原因)。
答案 1 :(得分:0)
也许有点晚了,但是我遇到了类似的情况,我通过使用run_in_executor在Flask中解决了这个问题:
def work(p):
# intensive work being done in the background
def endpoint():
p = ""
loop = asyncio.get_event_loop()
loop.run_in_executor(None, work, p)
我不确定这是否安全,因为没有关闭循环。
答案 2 :(得分:0)
假设同步函数位于异步函数内部,则可以使用异常来解决它。 伪代码:
class CustomError(Exception):
pass
async def main():
def test_syn():
time.sleep(2)
# Start Async
raise CustomError
try:
test_syn()
except CustomError:
await asyncio.sleep(2)