无法提升使用协程时返回工作状态

时间:2014-10-17 23:54:08

标签: python asynchronous tornado coroutine

我一直在尝试使用Python 2.7和Tornado 3.2。我一直试图让一个简单的协程示例工作,但没有太多运气:

import tornado.web
from tornado.gen import coroutine
from tornado.httpclient import AsyncHTTPClient
from tornado.gen import Return

class MainHandler(tornado.web.RequestHandler):

    # Tried with and without @asynchronous
    @tornado.web.asynchronous
    def get(self):
            data = MainService().get_google_data() 
            self.write(data)


class MainService:

    @coroutine
    def get_google_data(self):
            response = yield AsyncHTTPClient().fetch("http://www.google.com")
            raise Return(value = 'hello')

我希望这会写出“你好'当cURLing URL。相反,我得到:

...
File "/vagrant/venv/lib/python2.7/site-packages/tornado/web.py", line 656, in write
raise TypeError("write() only accepts bytes, unicode, and dict objects")
TypeError: write() only accepts bytes, unicode, and dict objects

显然,正在返回Future,但在未来调用result()会引发另一个异常:DummyFuture does not support blocking for results

Tornado文档说,为了从协程返回一个值,你会引发一个Return异常。看一下源代码,这似乎确实是预期的。然而,当我运行它时,它似乎无法工作。

感谢对此的任何见解!

1 个答案:

答案 0 :(得分:4)

您需要yield拨打get_google_data()

class MainHandler(tornado.web.RequestHandler):

    @coroutine
    def get(self):
        data = yield MainService().get_google_data() 
        self.write(data)

龙卷风协同程序总是返回Future。您可以通过调用Future来等待yield的结果。如果没有yield,您最终会立即返回Future,而无需等待协程完成。除了@coroutine之外,您还应该使用get方法上的get_google_data装饰器。如果你想使用回调而不是协同程序,通常会使用@asynchronous装饰器。