首页 > 代码库 > 用tornado 写异步回调程序

用tornado 写异步回调程序

用tornado,一般都用到它的 AsyncHTTPClient的 fetch。我们可以参考 fetch,使用tornado的特性,写异步回调程序

 

首先看看 fetch的实现,关键是用了future

def fetch(self, request, callback=None, **kwargs):        """Executes a request, asynchronously returning an `HTTPResponse`.        The request may be either a string URL or an `HTTPRequest` object.        If it is a string, we construct an `HTTPRequest` using any additional        kwargs: ``HTTPRequest(request, **kwargs)``        This method returns a `.Future` whose result is an        `HTTPResponse`.  The ``Future`` wil raise an `HTTPError` if        the request returned a non-200 response code.        If a ``callback`` is given, it will be invoked with the `HTTPResponse`.        In the callback interface, `HTTPError` is not automatically raised.        Instead, you must check the response‘s ``error`` attribute or        call its `~HTTPResponse.rethrow` method.        """        if not isinstance(request, HTTPRequest):            request = HTTPRequest(url=request, **kwargs)        # We may modify this (to add Host, Accept-Encoding, etc),        # so make sure we don‘t modify the caller‘s object.  This is also        # where normal dicts get converted to HTTPHeaders objects.        request.headers = httputil.HTTPHeaders(request.headers)        request = _RequestProxy(request, self.defaults)        future = TracebackFuture()        if callback is not None:            callback = stack_context.wrap(callback)            def handle_future(future):                exc = future.exception()                if isinstance(exc, HTTPError) and exc.response is not None:                    response = exc.response                elif exc is not None:                    response = HTTPResponse(                        request, 599, error=exc,                        request_time=time.time() - request.start_time)                else:                    response = future.result()                self.io_loop.add_callback(callback, response)            future.add_done_callback(handle_future)        def handle_response(response):            if response.error:                future.set_exception(response.error)            else:                future.set_result(response)        self.fetch_impl(request, handle_response)        return future

 

所以,只要用了future,我们也可以写异步代码

def test(callback=None):    future = TracebackFuture()    if callback is not None:        callback = stack_context.wrap(callback)        def handle_future(future):            response = future.result()            IOLoop.current().add_callback(callback, response)        future.add_done_callback(handle_future)    def handle_response(response=‘‘):        future.set_result(response)    test_func(handle_response)    return future

test_func里面,我就把函数handle_response传出去了,只要后续的操作,调用了handle_response,就会回调 函数handle_future,最后回调 函数callback

 

用tornado 写异步回调程序