龙卷风中的期货不能调用result()

时间:2015-07-01 21:47:06

标签: python tornado

我想使用python库tornado(版本4.2)做一些异步HTTP请求。但是,我可以强制完成未来(使用result()),因为我得到一个例外:“DummyFuture不支持阻止结果”。

我有python 3.4.3因此未来的支持应该是标准库的一部分。 concurrent.py的文档说:

  

如果可用,龙卷风将使用concurrent.futures.Future;   否则它将使用此模块中定义的兼容类。

以下提供了我尝试做的最小示例:

from tornado.httpclient import AsyncHTTPClient;

future = AsyncHTTPClient().fetch("http://google.com")
future.result()

如果我理解我的问题是正确的,因为以某种方式导入concurrent.futures.Future不会被使用。龙卷风中的相关代码似乎在concurrent.py中,但我并没有真正在理解问题所在的位置上取得进展。

1 个答案:

答案 0 :(得分:4)

尝试创建另一个Future并使用add_done_callback

From Tornado documentation

from tornado.concurrent import Future

def async_fetch_future(url):
    http_client = AsyncHTTPClient()
    my_future = Future()
    fetch_future = http_client.fetch(url)
    fetch_future.add_done_callback(
        lambda f: my_future.set_result(f.result()))
    return my_future

但你仍然需要用ioloop解决未来,像这样:

# -*- coding: utf-8 -*-
from tornado.concurrent import Future
from tornado.httpclient import AsyncHTTPClient
from tornado.ioloop import IOLoop


def async_fetch_future():
    http_client = AsyncHTTPClient()
    my_future = Future()
    fetch_future = http_client.fetch('http://www.google.com')
    fetch_future.add_done_callback(
        lambda f: my_future.set_result(f.result()))
    return my_future

response = IOLoop.current().run_sync(async_fetch_future)

print(response.body)

另一种方法是使用tornado.gen.coroutine装饰器,如下所示:

# -*- coding: utf-8 -*-
from tornado.gen import coroutine
from tornado.httpclient import AsyncHTTPClient
from tornado.ioloop import IOLoop


@coroutine
def async_fetch_future():
    http_client = AsyncHTTPClient()
    fetch_result = yield http_client.fetch('http://www.google.com')
    return fetch_result

result = IOLoop.current().run_sync(async_fetch_future)

print(result.body)

coroutine装饰器使函数返回Future