我试图获得一个非常简单的初始服务器,该服务器可以(异步地)获取一个URL,但是会抛出:

Exception: DummyFuture does not support blocking for results


有此SO帖子,但答案不包括运行Web服务器并尝试将Future添加到我的循环中,如here所示:

RuntimeError: IOLoop is already running


这是完整的代码:

import tornado.web
import tornado.gen
from tornado.httpclient import AsyncHTTPClient
from tornado.ioloop import IOLoop

URL = 'http://stackoverflow.com'


@tornado.gen.coroutine
def fetch_coroutine(url):
    http_client = AsyncHTTPClient()
    response = yield http_client.fetch(url)
    raise tornado.gen.Return(response.body)  # Python2


class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("Hello, world")


class FetchSyncHandler(tornado.web.RequestHandler):
    def get(self):
        data = fetch_coroutine(URL)
        print type(data)  # <class 'tornado.concurrent.Future'>
        self.write(data.result())


def make_app():
    return tornado.web.Application([
        (r"/", MainHandler),
        (r"/async", FetchSyncHandler),
    ])

if __name__ == "__main__":
    app = make_app()
    app.listen(9999)
    print 'starting loop'
    IOLoop.current().start()
    print 'loop stopped'


循环正在运行,返回前途。有什么问题

Python 2.7.10
龙卷风== 4.4.2

最佳答案

要从Future中获取结果,请在yield函数中将其gen.coroutine或在await本机协程中将其替换为async def。因此,将FetchSyncHandler替换为:

class FetchSyncHandler(tornado.web.RequestHandler):
    @gen.coroutine
    def get(self):
        data = yield fetch_coroutine(URL)
        self.write(data)


有关更多信息,请参见我的Refactoring Tornado CoroutinesTornado coroutine guide

10-06 12:09