2012-02-21 104 views
2

在一個簡單的異步情況下,處理程序可能看起來像:鏈異步操作(蟒蛇 - 龍捲風)

@tornado.web.authenticated 
@tornado.web.asynchronous 
def post(self): 
    AsyncHTTPClient().fetch("http://api.example.com/", self.on_post_response) 

def on_post_response(self, response): 
    self.render("template.html", status=response.error) 

不過,我已經到了一個點,當我需要執行兩個異步操作(獲取遠程休息api,然後發送帶有結果的郵件),然後返回給客戶端。

我不知道是否有「插入」的方式來做到這一點,例如,通過向隊列添加回調(如ioloop.add_callback),還是必須編寫一個自定義對象來管理這些任務及其狀態,並從post中調用它。

回答

4

您是否考慮過以下方法?

@tornado.web.authenticated 
@tornado.web.asynchronous 
def post(self): 
    async_fetch(..., self._on_fetch_response) 

def _on_fetch_response(self, response): 
    async_mail(response, self._on_mail_response) 

def _on_mail_response(self, response): 
    self.render(...) # render() automatically calls self.finish() 

或者使用tornado.gen

@asynchronous 
@gen.engine 
def post(self): 
    fetch_response = yield gen.Task(async_fetch, ...) 
    mail_response = yield gen.Task(async_mail, ...) 
    self.render(...) 
+0

可以幫助定義async_mail話,好像這是實際的幫助,我需要;-),是添加@Asynchronous裝飾,使每一個功能異步? – 2012-02-21 15:05:05

+2

'async_email()'只是一個虛構的例子,請參閱[tornadomail](https://github.com/equeny/tornadomail)瞭解異步SMTP客戶端。 @asynchronous修飾器使得請求處理器方法本身是異步的,但是處理器中的代碼仍然阻塞,除非它明確支持非阻塞執行,例如通過回調參數。因此,您需要特殊版本的IO庫(郵件,http,數據庫)來利用異步。 'gen.Task'就是同樣的語法糖。 – jholster 2012-02-21 18:16:13