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

时间:2018-02-27 16:44:43

标签: python http asynchronous request tornado

我有一个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

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

1 个答案:

答案 0 :(得分:0)

由于您知道AsyncHTTPClient是异步的,这意味着请求将在后台中运行。

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

这就是self.data为空的原因,因为请求尚未完成。

如何解决此问题

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

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