我想使用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()
Run Code Online (Sandbox Code Playgroud)
如果我理解我的问题是正确的,因为concurrent.futures.Future不使用某种方式导入.龙卷风中的相关代码似乎已经存在,concurrent.py但我并没有真正在理解问题究竟在哪里取得进展.
尝试创建另一个Future并使用add_done_callback:
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
Run Code Online (Sandbox Code Playgroud)
但是您仍然需要使用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)
Run Code Online (Sandbox Code Playgroud)
另一种方法是使用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)
Run Code Online (Sandbox Code Playgroud)
coroutine装饰器使函数返回Future。