1 装饰器 + Future 从而实现Tornado的异步非阻塞
class AsyncHandler(tornado.web.RequestHandler):
@gen.coroutine
def get(self):
future = Future()
future.add_done_callback(self.doing)
yield future
# 或
# tornado.ioloop.IOLoop.current().add_future(future,self.doing)
# yield future
def doing(self,*args, **kwargs):
self.write('async')
self.finish()
当发送GET请求时,由于方法被@gen.coroutine装饰且yield 一个 Future对象,那么Tornado会等待,等待用户向future对象中放置数据或者发送信号,如果获取到数据或信号之后,就开始执行doing方法。
异步非阻塞体现在当在Tornaod等待用户向future对象中放置数据时,还可以处理其他请求。
注意:在等待用户向future对象中放置数据或信号时,此连接是不断开的。
2 同步阻塞和异步非阻塞
# 同步阻塞
class SyncHandler(tornado.web.RequestHandler):
def get(self):
self.doing()
self.write('sync')
# 异步非阻塞
class AsyncHandler(tornado.web.RequestHandler):
@gen.coroutine
def get(self):
future = Future()
tornado.ioloop.IOLoop.current().add_timeout(time.time() + 5, self.doing)
yield future
def doing(self, *args, **kwargs):
self.write('async')
self.finish()
def doing(self):
time.sleep(10)
3 httpclient类库用于发送Http请求,配合Tornado的异步非阻塞使用
import tornado.web
from tornado import gen
from tornado import httpclient
# 方式一:
class AsyncHandler(tornado.web.RequestHandler):
@gen.coroutine
def get(self, *args, **kwargs):
print('进入')
http = httpclient.AsyncHTTPClient()
data = yield http.fetch("http://www.google.com")
print('完事',data)
self.finish('6666')
# 方式二:
# class AsyncHandler(tornado.web.RequestHandler):
# @gen.coroutine
# def get(self):
# print('进入')
# http = httpclient.AsyncHTTPClient()
# yield http.fetch("http://www.google.com", self.done)
#
# def done(self, response):
# print('完事')
# self.finish('666')
application = tornado.web.Application([
(r"/async", AsyncHandler),
])
if __name__ == "__main__":
application.listen(8888)
tornado.ioloop.IOLoop.instance().start()