2012-06-27 77 views
2

我有很多的代碼在我的龍捲風應用程序,它看起來是這樣的:相當於Tornado中的@inlineCallbacks?

@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中的代碼?

回答

2

找到它。在龍捲風中,它不叫做內聯回調,而是「基於生成器的接口」— 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() 
+0

是的,這是自龍捲風版本'2.1'以來直接回答你的問題。 –

+0

@NikolayFominyh:在2.0版本中我開始使用Tornado,升級時肯定錯過了「新增功能」;-) – vartec

4

你甚至可以因數分解調用。

我認爲你所做的是在另一個之後調用一個異步調用,因此不會給出最大延遲改進。

如果電話沒有任何相關性(例如像以一個調用的結果做第二個呼叫),你可以同時啓動所有來電:

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

這樣一來,所有呼叫開始在同時,因此您的總體延遲是最大(所有呼叫)而不是總和(所有呼叫)。

我已經在需要聚合許多第三方WS或數據庫調用的應用程序中使用它,並且它總體上延遲了很多。

當然,如果有兩個電話之間的依賴關係(如上mentionned)它不工作

+1

實際上,在我的情況下,調用並不是獨立的,它們之間有一些額外的代碼,但它是無論如何有趣的觀察。 – vartec

2

你也可以考慮只用Cyclone,這將允許您使用@inlineCallbacks(以及任何其他扭曲的代碼,你想)直接。