码迷,mamicode.com
首页 > 其他好文 > 详细

Tornado 框架中异步与非阻塞编程代码说明

时间:2015-04-26 09:37:01      阅读:408      评论:0      收藏:0      [点我收藏+]

标签:

tornad官方文档的Docs》User’s guide》Asynchronous and non-Blocking I/O部分,文中提供了几段示例代码:

 a、同步请求代码

from tornado.httpclient import HTTPClient

def synchronous_fetch(url):
    http_client = HTTPClient()
    response = http_client.fetch(url)
    return response.body

b、带回调函数的异步请求代码

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)

c、使用一个 Future  对象替换掉回掉函数

from tornado.concurrent import Future
def async_fetch_future(url):
    http_client = AsyncHTTPClient()
    my_future = Future()
    fetch_future = http_client.fetch(url)
    fetch_future.add_done_callback(
        lambda f: my_future.set_result(f.result()))
    return my_future

d、使用@gen.coroutine装饰的异步请求方式

from tornado import gen@gen.coroutinedef fetch_coroutine(url):
    http_client = AsyncHTTPClient()
    response = yield http_client.fetch(url)
    raise gen.Return(response.body)

下面对这4段代码进行测试:

首先准备数据服务:

        URL:’http://localhost:8080/rest/menu‘

        METHOD:‘GET‘

        返回数据类型:JSON

a.同步请求方法直接调用方法请求,即可得到数据

from tornado.httpclient import HTTPClient

def synchronous_fetch(url):
    """
    简单HttpClient的同步请求
    :param url:
    :return:
    """
    http_client = HTTPClient()
    response = http_client.fetch(url)
    return response.body

def parse_body(body):
    """
    解析请求返回值,异步回调函数
    :param body:
    :return:
    """
    print("函数被回调")
    for line in json.loads(body.decode(encoding=‘utf8‘)):
        print(line)
        
if __name__ == ‘__main__‘:
    url = "http://localhost:8080/rest/menu"
    # 同步请求调用方式
    body = synchronous_fetch(url)
    parse_body(body)

b、异步回调请求,需要将回调事件增加到IOLoop事件监听队列中,才可触发回调函数

def parse_body(body):
    """
    解析请求返回值,异步回调函数
    :param body:
    :return:
    """
    print("函数被回调")
    for line in json.loads(body.decode(encoding=‘utf8‘)):
        print(line)

def asynchronous_fetch(url, callback):
    """
    异步请求方法,带回调函数
    :param url:
    :param callback:
    :return:
    """
    http_client = AsyncHTTPClient()

    def handle_response(response):
        callback(response.body)

    http_client.fetch(url, callback=handle_response)
    # 注意此处,需要启动IOLoop实例才能触发回调
    IOLoop.instance().start()

    
 if __name__ == ‘__main__‘:
    url = "http://localhost:8080/rest/menu"
    # 异步请求,带回调函数
    # asynchronous_fetch(url, callback=parse_body)

c、IOLoop提供了专门的方法add_future()来注册Futrue的回调事件,代码中应用了lamada表达式

def futrue_callback(res_future):
    print("调用回调函数 Futrue")
    parse_body(res_future._result.body)


def async_fetch_future(url):
    """
    异步请求,使用Future类
    :param url:
    :return:
    """
    http_client = AsyncHTTPClient()
    my_future = Future()
    fetch_future = http_client.fetch(url)
    fetch_future.add_done_callback(
        # Future的result默认为HttpResponce
        lambda f: my_future.set_result(f.result()))
    return my_future
    
if __name__ == ‘__main__‘:
    url = "http://localhost:8080/rest/menu"
    # 异步请求,返回Futrue类
    future = async_fetch_future(url)
    io_loop = IOLoop.current()
    io_loop.add_future(future, callback=futrue_callback)
    io_loop.start()

d、@gen.coroutine实现了对Future内部回调的封装,因此使用@gen.conroutine使代码更加清晰,内部机制未变,因此调用方式未变

def parse_body(body):
    """
    解析请求返回值,异步回调函数
    :param body:
    :return:
    """
    print("函数被回调")
    for line in json.loads(body.decode(encoding=‘utf8‘)):
        print(line)

def futrue_callback(res_future):
    print("调用回调函数 Futrue")
    parse_body(res_future._result.body)


@gen.coroutine
def fetch_coroutine(url):
    http_client = AsyncHTTPClient()
    response = yield http_client.fetch(url)
    return response


if __name__ == ‘__main__‘:
    url = "http://localhost:8080/rest/menu"
    # 使用协程调用
    gen_future = fetch_coroutine(url)
    io_loop = IOLoop.current()
    io_loop.add_future(gen_future, callback=futrue_callback)
    io_loop.start()


 下一步需要深入学习的是:

    1、IOLoop的实现原理与事件注册机制


























Tornado 框架中异步与非阻塞编程代码说明

标签:

原文地址:http://my.oschina.net/zhgk/blog/406394

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!