竜巻のドキュメントの紹介ページに記載されている基本的な例を理解しようとしています。 2ブロックのコードがあります。同期のものは私にとっては問題ありません、そして私はそれを理解しています。しかし、非同期のものは私が理解できないものです。
同期
from tornado.httpclient import HTTPClient
def synchronous_fetch(url):
http_client = HTTPClient()
response = http_client.fetch(url)
return response.body
非同期
from tornado.httpclient import AsyncHTTPClient
def asynchronous_fetch(url, callback):
http_client = AsyncHTTPClient()
def handle_response(response):
callback(response.body)
http_client.fetch(url, callback=handle_response)
より良い例を提供できる場合は、そうしてください。
非同期呼び出しの考え方は、多くのWeb関連プログラミングでほぼ同じように機能します... "stuff"(frameworks 、サーバー、ライブラリ...)TornadoWebサーバーの概念だけではありません。
基本的な考え方は次のとおりです。
A̲s̲y̲n̲c̲h̲r̲o̲n̲o̲u̲s̲リクエストでは、リクエストを「起動」、一種の「忘れる」、つまり、インタプリタは続行しますリクエストが完了した後、リクエストが完了するのを待たずにコードを実行します。
これは...かなり無意味なようですよね?リクエストを「スペースのない場所に」送信し、通常どおり実行を続けますか?サーバーが応答を送信するとどうなりますか?リクエストしたのですが、どうしたのか知りたいです!そうでなければ、そもそもコードにそれを入力していなかっただろう!
さて、ここでcallback
が入ります。リクエスト "をスペースのない場所に"[〜#〜 ] but [〜#〜]コールバック関数を提供するので、相手側のHTTPサーバーが応答を送信すると、その関数は最初に上記のresponse
を使用して実行されます。引数。
Enの例でそれを見てみましょう。
ハンドラーが1つだけの非常に単純なTornadoサーバー(Python 2.7
とTornado 4.2
を使用)を作成しました。 GET
では、戻るのに5秒かかります。 time.sleep でそれを実行しましたが、実際には、非常に時間のかかるプロセスになる可能性があります(データベースにアクセスし、計算を実行します...誰が知っていますか?...)
サーバーファイルは次のとおりです(Tornadoのドキュメントで提供されている 例 に基づく):
SampleServer.py
:#!/usr/bin/env python2.7
import time
import tornado.ioloop
import tornado.web
class MainHandler(tornado.web.RequestHandler):
def get(self):
print "Someone is GET'ing me"
time.sleep(5)
self.write("Hello, world")
application = tornado.web.Application([
(r"/", MainHandler),
])
if __name__ == "__main__":
application.listen(8888)
print "Starting sample server."
tornado.ioloop.IOLoop.current().start()
ターミナルを開き、そのコードを実行してサーバーを作成します。ローカルマシンのポート8888
でトルネードがリッスンします。
次に、2つの方法でGET
s http://localhost:8888
する別のスクリプト(別の端末で実行する必要があります)を作成しましょう。最初は同期、次に非同期です。
SampleFetcher.py
:#!/usr/bin/env python2.7
import datetime
import tornado.ioloop
from tornado.httpclient import HTTPClient, AsyncHTTPClient
def HUMAN_DT_NOW():
return datetime.datetime.now().strftime("%Y/%m/%d %H:%M:%S")
def synchronous_fetch(url):
http_client = HTTPClient()
start_dt = datetime.datetime.now()
response = http_client.fetch(url)
end_dt = datetime.datetime.now()
print ("The synchronous fetch took %s seconds."
% (end_dt - start_dt).total_seconds())
print "(Sync) Server said: \"%s\"" % response.body
def asynchronous_fetch(url):
http_client = AsyncHTTPClient()
def handle_response(response):
print ""
print "Yawwza... Finally!!!."
print "The time now is %s" % HUMAN_DT_NOW()
print "(Async) Server said: \"%s\"" % response.body
print "Gonna launch a 'fetch' to the universe at %s..." % HUMAN_DT_NOW()
http_client.fetch(url, callback=handle_response)
if __name__ == "__main__":
print " ------ Synchronous ------ "
print ("Starting synchronous fetch at %s."
" The program will block for about 5 secs." % HUMAN_DT_NOW())
synchronous_fetch('http://localhost:8888')
print "Pfew! That was a lot of wait time!!. I got bored watching my terminal"
print ""
print "Aight, let's see what Asynchronous can do"
print " ------ Asynchronous ------ "
asynchronous_fetch('http://localhost:8888')
print "You're gonna see this line before the \"Yawwza...\" one"
print "This one too. Now is %s" % HUMAN_DT_NOW()
# The IOLoop below is required to prevent the script from closing ahead
# of time, but allowing Asynchronous interactions
tornado.ioloop.IOLoop.current().start()
これは出力します:
Starting synchronous fetch at 2015/07/04 13:25:47. The program will block for about 5 secs.
The synchronous fetch took 5.009597 seconds.
(Sync) Server said: "Hello, world"
Pfew! That was a lot of wait time!!. I got bored watching my terminal
Aight, let's see what Asynchronous can do
------ Asynchronous ------
Gonna launch a 'fetch' to the universe at 2015/07/04 13:25:52...
You're gonna see this line before the "Yawwza..." one
This one too. Now is 2015/07/04 13:25:52
Yawwza... Finally!!!.
The time now is 2015/07/04 13:25:57
(Async) Server said: "Hello, world"
ここでは、非同期部分に焦点を当てましょう。
------ Asynchronous ------
Gonna launch a 'fetch' to the universe at 2015/07/04 13:25:52...
You're gonna see this line before the "Yawwza..." one
This one too. Now is 2015/07/04 13:25:52
Yawwza... Finally!!!.
The time now is 2015/07/04 13:25:57
(Async) Server said: "Hello, world"
ご覧のとおり、スクリプトはasynchronous_fetch
を13:25:52
で作成しましたが、すぐに(同じ秒で)、インタプリタは続行しました実行し、要求が行われた後に次のステートメントを実行します(You're gonna see this line before the "Yawwza..." one
およびThis one too. Now is 2015/07/04 13:25:52
を出力する行)。
次に、約5秒後、サーバーが応答し、callback
関数(handle_response
でした)が実行されました。
Yawwza... Finally!!!.
The time now is 2015/07/04 13:25:57
これがアイデアの理解に少し役立つことを願っています。これは非常に便利な概念であり、トルネードだけに適用されるわけではありません。
提供されている2つのサンプルスクリプトを自由に試して、変更を加え、サーバーが応答するまでの時間を増やしてください...
さらに推奨される読み物: