实现自己的gen.engine和gen.Task

来源:互联网 发布:sql sum函数 编辑:程序博客网 时间:2024/06/07 03:05

在之前,我们有说过tornado的web异步调用。今天我们来分析一下。

先看下面的代码。

# -*- coding:utf-8 -*-from tornado import ioloop, httpclientdef deal(response):    print 'response.length =', len(response.body)    ioloop.IOLoop.instance().stop()def download(url):    http_client = httpclient.AsyncHTTPClient()    http_client.fetch(url, deal)download("http://www.baidu.com/")    ioloop.IOLoop.instance().start()

结果如下:

response.length = 10233

很明显的可以看出。http_client的fetch只是一个异步调用。需要传递一个deal方法,作为callback来去处理fetch后的response。

如果我们用tornado的gen.engine方式可以这样写:

from tornado import ioloop, httpclient, genfrom tornado.gen import Task@gen.enginedef download(url):    http_client = httpclient.AsyncHTTPClient()    response = yield Task(http_client.fetch, url)    print 'response.length =', len(response.body)     ioloop.IOLoop.instance().stop()download("http://www.baidu.com/")ioloop.IOLoop.instance().start()

这样就好像你在写同步代码一样。而不需要想之前那样处理回调了。

下面我们考虑,如果要你实现一个gen.engine 和 Task 你会怎么实现呢?

根据我们之前谈的yield 和 generator,我们可以这样写代码:

# -*- coding:utf-8 -*-from tornado import ioloop, httpclientimport functoolsclass MyTask(object):    def __init__(self, func, *args, **kwargs):        self.func = func        self.args = args        self.kwargs = kwargs    def callback(self, response):        try:            self.gen.send(response)        except StopIteration:            pass    def run(self, gen):        self.gen = gen        partail_func = functools.partial(self.func, *self.args, **self.kwargs)        partail_func(callback = self.callback)def myengine(func):    def _(*args, **kwargs):        task_generator = func(*args, **kwargs)        task = task_generator.next()        task.run(task_generator)    return _@myenginedef download(url):    http_client = httpclient.AsyncHTTPClient()    response = yield MyTask(http_client.fetch, url)    print 'response.length =', len(response.body)    ioloop.IOLoop.instance().stop()download("http://www.baidu.com/")ioloop.IOLoop.instance().start()

这个时候,结果是:

response.length = 10233

这样,属于我们自己的engine和task就出来了。

0 0
原创粉丝点击