2012-02-21 3 views
2

は、単純な非同期の場合、ハンドラは次のようになります。私は2つの非同期操作を(実行する必要がある場合は(のpython - 竜巻)クライアントに書き込む前に非同期操作の連鎖

@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デコレータは、すべての関数の非同期を作る追加されますか? –

+2

'async_email()'は単なる架空の例です。非同期SMTPクライアントの場合は、[tornadomail](https://github.com/equeny/tornadomail)を参照してください。 @asynchronousデコレータは、要求ハンドラメソッド自体を非同期にしますが、ハンドラ内のコードは、非ブロック実行を明示的にサポートしない限り、ブロックされます。 viaコールバックパラメータ。したがって、非同期性を利用するには特別なバージョンのIOライブラリ(メール、http、データベース)が必要です。 'gen.Task'は同じものの構文的な砂糖です。 – jholster

関連する問題