相当于龙卷风中的@inlineCallbacks?

时间:2012-06-27 12:36:59

标签: python callback twisted tornado

我的Tornado应用程序中有很多代码,如下所示:

@tornado.web.asynchronous
def get(self):
    ...
    some_async_call(..., callback=self._step1)

def _step1(self, response):
    ...
    some_async_call(..., callback=self._step2)

def _step2(self, response):
    ...
    some_async_call(..., callback=self._finish_request)


def _finish_request(self, response):
    ...
    self.write(something)
    self.finish()

显然内联回调会简化代码,看起来像是:

@inlineCallbacks
@tornado.web.asynchronous
def get(self):
    ...
    response = yield some_async_call(...)
    ...
    response = yield some_async_call(...)
    ...
    response = yield some_async_call(...)
    ...
    self.write(something)
    self.finish()

有没有办法在Tornado中进行内联回调或以其他方式简化代码?

3 个答案:

答案 0 :(得分:4)

你甚至可以将呼叫分解。

我认为你所做的就是在另一个之后调用一个异步调用,因此不能提供最大的延迟改进。

如果呼叫没有任何依赖关系(例如,将一个呼叫的结果用于进行第二次呼叫),您可以同时启动所有呼叫:

@tornado.web.asynchronous
@gen.engine
def get(self):
    responses = yield [ gen.Task(call) for call in required_calls ]

这样,所有呼叫都会同时启动,因此您的整体延迟是最大(所有呼叫)而不是总和(所有呼叫)。

我在一个需要聚合许多第三方WS或数据库调用的应用程序中使用它,并且它大大改善了整体延迟。

当然,如果调用之间存在依赖关系(如上所述)

,则它不起作用

答案 1 :(得分:2)

找到它。在Tornado中,它不是内联回调,而是“基于生成器的界面” - tornado.gen。因此,我的代码应该类似于:

@tornado.web.asynchronous
@gen.engine
def get(self):
    ...
    response = yield gen.Task(some_async_call(...))
    ...
    response = yield gen.Task(some_async_call(...))
    ...
    response = yield gen.Task(some_async_call(...))
    ...
    self.write(something)
    self.finish()

答案 2 :(得分:2)

您也可以考虑使用Cyclone,这样您就可以直接使用@inlineCallbacks(以及您想要的任何其他Twisted代码)。