前面介绍了异步方法带来的显著性能提升。我们来看下异步使用的方法。
1 首先对于get方法使用tornado.web.asynchronous进行装饰。当使用tornado.web.asynchronous进行装饰的时候,Tornado不会自己关闭连接。
你必须在你的RequestHandler对象中调用finish方法来显式地告诉Tornado关闭连接否则,请求将可能挂起,浏览器可能不会显示我们已经发送给客户端的数据。)。简单点来说,就是在RequestHandler中,_auto_finish被初始化为True,在get函数执行完后自动执行self.finish函数来结束连接。但是如果get被asynchronous装饰后,_auto_finish将会被设置为False 这样除非手动调用self.finish。也就是在回调函数中等获取到目标url的信息后执行self.finish。在这期间,创建的是非阻塞的socket连接(AsyncHTTPClient)。在等待目标URL反馈的期间控制权交给ioloop中去运行其他的连接。等到数据就绪之后再切回来。使异步变得可能。这就有点像一个时分系统,当任务A还未完成的时候,起一个中断然后继续运行任务B,等到任务A的响应数据到来。继续执行任务A。避免了任务A的超长处理导致任务阻塞。
异步生成器:
当我们有两个或更多的异步请求要执行的时候,编码和维护都显得非常困难,每个都依赖于前面的调用:不久你就会发现自己调用了一个回调函数的回调函数的回调函数。下面就是一个例子:在一个get函数触发中,需要获取不同的url内容。有多少个url我们就得写多少个不同的回调函数。
def get(self):
client = AsyncHTTPClient()
client.fetch("http://example.com", callback=on_response)
def on_response(self, response):
client = AsyncHTTPClient()
client.fetch("http://another.example.com/", callback=on_response2)
def on_response2(self, response):
client = AsyncHTTPClient()
client.fetch("http://still.another.example.com/", callback=on_response3)
def on_response3(self, response):
[etc., etc.]
tornado提供了一个更为简介的方法来实现这种情况。下面是示例代码:
class indexHandler_test1(tornado.web.RequestHandler):
@tornado.web.asynchronous
@tornado.gen.engine
def get(self, *args, **kwargs):
query = self.get_argument('a').encode('utf-8')
url2='http://tcc.taobao.com/cc/json/mobile_tel_segment.htm?tel=13541078274'
client = tornado.httpclient.AsyncHTTPClient()
response=yield tornado.gen.Task(client.fetch,("http://gc.ditu.aliyun.com/geocoding?"+urllib.urlencode({'a':query})))
print response.body
response1 = yield tornado.gen.Task(client.fetch,(url2))
print response1.body
self.write(response.body+'
'+(response1.body).decode('GB2312').encode('utf-8'))
self.finish()
首先采用@tornado.gen.engine对其进行装饰,且必须位于get函数之前。然后采用yield关键字产生2个task分别指向不同的url。最终将两个url的返回结果整合在一起显示在网页上
我们使用Python的yield关键字以及tornado.gen.Task对象的一个实例,将我们想要的调用和传给该调用函数的参数传递给那个函数。这里,yield的使用返回程序对Tornado的控制,允许在HTTP请求进行中执行其他任务。当HTTP请求完成时,RequestHandler方法在其停止的地方恢复。这种构建的美在于它在请求处理程序中返回HTTP响应,而不是回调函数中。因此,代码更易理解:所有请求相关的逻辑位于同一个位置。而HTTP请求依然是异步执行的,所以我们使用tornado.gen可以达到和使用回调函数的异步请求版本相同的性能。