Asynchronous tornado,在完成时进行异步

Asynchronous tornado,在完成时进行异步,asynchronous,tornado,coroutine,Asynchronous,Tornado,Coroutine,覆盖_finish()上的方法。 用.gen.coroutine装饰此方法,使其异步,它可以工作 @gen.coroutine def on_finish(self): print("==========on_finish==============") 但是使用async def使其异步,它失败了 async def on_finish(self): print("==========on_finish==============") # RuntimeWarning: c

覆盖_finish()上的方法。 用
.gen.coroutine
装饰此方法,使其异步,它可以工作

@gen.coroutine
def on_finish(self):
    print("==========on_finish==============")
但是使用
async def
使其异步,它失败了

async def on_finish(self):
    print("==========on_finish==============")

# RuntimeWarning: coroutine 'BaseHandler.on_finish' was never awaited
self.on_finish()


为什么我不能使用
async def
使其异步?

协同程序的接口与常规函数不同。重写方法时,应根据其文档将其设置为协同程序(或非协同程序)。Tornado中所有可能是协同路由的可重写方法在其文档中都是这样说的,并且在_finish上的
不是其中之一

如果在超类不期望的情况下使用协程,会发生什么?如您所见,这取决于协同程序的类型
@gen.corroutine
是“自启动”的,所以corroutine将启动,但不会等待它完成,如果它引发异常,则无法捕获该异常(因此它将由IOLoop记录)
async def
corroutines不会自动启动,必须有一些东西等待它们,因此如果在调用方不希望使用corroutine的情况下使用,则不会发生任何事情

如果您需要从一个不允许使用协同路由的方法中使用协同路由,那么您需要决定谁将等待协同路由并处理其异常。如果您不需要捕获异常,只需将异常留给日志,则可以使用
IOLoop.add\u callback
将此职责明确赋予IOLoop:

def on_finish(self):
    IOLoop.current().add_callback(self.on_finish_async)

async def on_finish_async(self):
    ...

我想是因为。您的第一个示例不起作用,它只是没有引发任何错误,因为它在语法上是正确的,并且无声地失败了。我在
add\u callback()
调用中看到了可能的解决方法。是的,Fian是对的。Tornado不支持将
on_finish
设置为异步函数。但是你想做什么呢?为什么要使其异步?我使用TorMySQL异步连接mysql。在prepare()函数中,我得到一个db.conn(),我想在on_finish()函数中自动关闭连接。函数db.conn.close()必须是asynchronous@Lvxiuquan正如Fian已经指出的那样,您可以通过使用
add\u callback()
方法来计划关闭连接。Tornado将异步运行它。如果您愿意,我可以发布示例代码。@xyres不用麻烦了。我明白了,谢谢。