python tornado获得多个异步httprequest的响应

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python tornado获得多个异步httprequest的响应相关的知识,希望对你有一定的参考价值。

我有一个url_handler列表,我想使用龙卷风制作异步的httprequest。当所有响应结构到达时,我需要将其用于其他目标。这是我的代码的一个简单示例:

(...)
self.number = 0
self.counter = 0
self.data = {}
(...)
@tornado.web.asynchronous
def post(self):
    list_url = [url_service1, url_service2]
    self.number = len(list_url)
    http_client = AsyncHTTPClient()
    for service in list_url:
        request = tornado.httpclient.HTTPRequest(url=service, method='POST', headers={'content-type': 'application/json'}, body=json.dumps({..params..}))
        http_client.fetch(request, callback=self.handle_response)

    # Loop for is finished. Use self.data for example in other funcions...
    # if i print(self.data) i have empty dict...
    # do_something(self.data)



def handle_response(self,response):
    if response.error:
        print("Error")
    else:
        self.counter = self.counter + 1
        print("Response {} / {} from {}".format(self.counter, self.number, response.effective_url))
        self.data[response.effective_url] = json_decode(response.body)
    # number is 2
    if self.counter == self.number:
        print("Finish response")

def do_something(data):
    # code with data parameter

我希望我的问题得到很好的解释

答案

既然你知道AsyncHTTPClient是异步的,那意味着请求将在后台运行。

因此,当for循环完成时,这并不意味着所有请求都已完成 - 即使循环结束,它们也在后台运行。

这就是为什么self.data是空的,因为请求还没有完成。


如何解决这个问题

如您所知,在每个请求完成后调用handle_response回调。所有请求完成后,您可以从此回调中调用do_something函数。像这样:

def handle_response(...):
    ...
    if self.counter == self.number:
        self.do_something(self.data)
        print("Finish response")

以上是关于python tornado获得多个异步httprequest的响应的主要内容,如果未能解决你的问题,请参考以下文章

Python web框架 Tornado异步非阻塞

Python学习---IO的异步[tornado模块]

python tornado异步性能测试

Python开发Tornado:异步Web服务

在 Tornado Web 服务器上运行 Django 以获得异步 + django admin + django orm 可能性的最佳方法是啥?

tornado6与python3.7,异步新姿势