• 用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

  • 相关阅读:
    ant-design-vue——子组件通过$parent修改父组件的值时无效问题及解决方法
    vue——quill-editor自定义图片上传
    ES6——var、let、const三者的区别
    js——数组/对象常用方法总结
    28.最长回文子序列
    27.马拉车
    26.扫雷一次点击
    JS添加内容之方法里传AJAX参数
    JQ 实现加载其他页面的H5代码 JQ加载H5独立导航栏代码
    CentOS 7不能上网 解决方法
  • 原文地址:https://www.cnblogs.com/yemsheng/p/4194751.html
Copyright © 2020-2023  润新知