phr*_*iac 12 python asynchronous callback tornado synchronous
我想了解龙卷风文档介绍页面上提供的基本示例.它有2个代码块.同步一个对我来说很好,我也理解它.但异步的是我无法理解的.
同步
from tornado.httpclient import HTTPClient
def synchronous_fetch(url):
http_client = HTTPClient()
response = http_client.fetch(url)
return response.body
Run Code Online (Sandbox Code Playgroud)
异步
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)
Run Code Online (Sandbox Code Playgroud)
如果您能提供更好的示例,请执行此操作.
Bor*_*jaX 34
在许多与Web相关的编程中,异步调用的思想几乎相同...... "东西"(框架,服务器,库......)不仅是Tornado Web服务器的概念.
基本思路是:
在异步请求中,您"启动"请求,并且有点"忘记它",这意味着:解释器在请求发出后继续执行代码,而不等待请求完成.
这似乎......毫无意义,对吧?你发送请求"空间无效",并继续像往常一样执行?当服务器向您发送响应时会发生什么?我提出了要求,我想知道发生了什么事!否则,我不会在我的代码中键入它开始!!
好吧,这就是它的callback用武之地.你启动了"空间空白" 的请求但是你提供了一个回调函数,所以当另一端的HTTP服务器向你发送它的响应时,该函数以所述response的第一个参数运行.
让我们看一下en例子吧.
我创建了一个非常简单的Tornado服务器(使用Python 2.7和Tornado 4.2)只有一个处理程序.在a上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()
Run Code Online (Sandbox Code Playgroud)
打开终端并运行该代码以获得服务器.你会得到一个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()
Run Code Online (Sandbox Code Playgroud)
这将输出:
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"
Run Code Online (Sandbox Code Playgroud)
让我们关注异步部分,这里:
------ 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"
Run Code Online (Sandbox Code Playgroud)
如果你看到,脚本发出了asynchronous_fetchat 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
Run Code Online (Sandbox Code Playgroud)
我希望这有助于理解这个想法.这是一个非常有用的概念,它不仅适用于龙卷风.
随意使用提供的两个示例脚本,更改内容,增加服务器回复的时间...
进一步推荐阅读: