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
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
手头没有电脑,先提供一点思路,一会儿验证一下
ioloop的add_future方法可以为future添加callback,先获取http_client的future,然后用add_future方法添加callback,最后再封装成一个新的future,yield新的future就可以了。
伪代码如下
测试了一下,功能可以实现
使用的时候可以
题主的第二个要求没看懂,如果第i个请求返回,就返回yield,那直接yield第i个请求就好了,其他的请求不用yield。
后续如果想继续等待下一个future返回,还可以
第二版