tornado在同时发出n个请求时,如何让其中1个有结果就返回?

发布于 2022-09-04 01:01:40 字数 284 浏览 20 评论 0

我知道tornado可以用如下方式,同时并发n个请求:

response1, response2,... responsen = yield [http_client.fetch(url1) , http_client.fetch(url2), ...... ,http_client.fetch(url2) ]

等到n个请求都响应了之后,会返回给程序控制权,那么我的问题是:

1.如果我想其中一个有结果了,就返回yield继续执行,应该怎么实现?

2.如果我要让其中i个请求有结果了就返回呢?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

一城柳絮吹成雪 2022-09-11 01:01:40

手头没有电脑,先提供一点思路,一会儿验证一下

ioloop的add_future方法可以为future添加callback,先获取http_client的future,然后用add_future方法添加callback,最后再封装成一个新的future,yield新的future就可以了。

伪代码如下

def get_first_result(futures):
    ret = tornado.gen.Future()

    def on_result(finished_future):
        
        if ret.done():
            return
        if finished_future.exception():
            return
        ret.set_result({"index": futures.index(finished_future), "result": finished_future})
    for i in futures:
        ioloop.add_future(i, on_result)
    return ret
    

测试了一下,功能可以实现

使用的时候可以

@tornado.gen.coroutine
def get_baidu():
    f1 = http_client.fetch("http://www.google.com")
    f2 = http_client.fetch("http://www.google.com")
    f3 = http_client.fetch("http://www.google.com")
    f4 = http_client.fetch("http://www.baidu.com")
    futures = [f1, f2, f3, f4]
    result = yield get_first_result(futures)
    print(result['result'].body)
    print(result['index'])
    print("resolved future " + str(futures[result['index']]))
    

题主的第二个要求没看懂,如果第i个请求返回,就返回yield,那直接yield第i个请求就好了,其他的请求不用yield。

后续如果想继续等待下一个future返回,还可以

futures.pop(result['index'])
result = yield get_first_result(futures)

第二版

def get_first_result(futures, count=1):
    ret = tornado.gen.Future()
    results = []
    def on_result(finished_future):
        
        if ret.done():
            return
        if finished_future.exception():
            return
        results.append({"index": futures.index(finished_future), "result": finished_future})
        if len(result) == count:
            ret.set_result(results)
    for i in futures:
        ioloop.add_future(i, on_result)
    return ret
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文