2012-02-21 100 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