Tornado 异步非阻塞


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()
原文地址:https://www.cnblogs.com/big-handsome-guy/p/8661101.html