用tornado,通常都用到它的 AsyncHTTPClient的 fetch。咱們能夠參考 fetch,使用tornado的特性,寫異步回調程序異步
首先看看 fetch的實現,關鍵是用了futureasync
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,最後回調 函數callbacktornado