我想了解龙卷风文档介绍页面上提供的基本示例。它有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)
如果您能提供更好的示例,请执行此操作。
答案 0 :(得分:31)
异步调用的想法在许多与Web相关的编程中几乎相同... “stuff”(框架,服务器,库...... )不仅是Tornado Web服务器的概念。
基本理念是:
在异步请求中,您“启动”请求,并且您“忘掉它”,这意味着:解释器继续执行代码之后无需等待请求即可完成请求。
这似乎......毫无意义,对吧?您将请求“发送到空白空间”,并继续照常执行?当服务器向您发送响应时会发生什么?我提出了要求,我想知道发生了什么事!否则,我不会在我的代码中键入,以开始!!
嗯,这是callback
进来的地方。你启动请求“到空白空间” 但是你提供了一个回调函数,所以当另一端的HTTP服务器向您发送响应,该函数以所述response
作为第一个参数运行。
让我们看一下例子。
我创建了一个非常简单的Tornado服务器(使用Python 2.7
和Tornado 4.2
)只有一个处理程序。在GET
上,返回需要5秒钟。我用time.sleep完成了这个,但在现实生活中,这可能是一个非常耗时的过程(访问数据库,执行一些计算......谁知道?...)
这是服务器文件(基于Tornado文档中提供的example):
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()
打开终端并运行该代码以获得服务器。您将获得Tornado监听本地计算机的端口8888
。
现在,让我们以两种方式创建另一个脚本(您必须在另一个终端中运行)GET
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
我希望这有助于理解这个想法。这是一个非常有用的概念,它不仅适用于龙卷风。
随意使用提供的两个示例脚本,更改内容,增加服务器回复的时间......
进一步推荐阅读: