zoukankan      html  css  js  c++  java
  • 用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

  • 相关阅读:
    Service Discovery
    Spring security框架原理
    Redis作者谈Redis应用场景
    redis持久化RDB和AOF-转载
    MongoDB树形结构表示法
    Tomcat Connector
    ActiveMQ 负载均衡与高可用(转载)
    JS选取DOM元素的方法
    IObit Driver Booster 无法更新驱动的解决办法
    python 学习备忘
  • 原文地址:https://www.cnblogs.com/yemsheng/p/4194751.html
Copyright © 2011-2022 走看看