龙卷风协程

kli*_*s87 13 python tornado

我正在尝试学习龙卷风协同程序,但我使用下面的代码有错误.

Traceback (most recent call last):
  File "D:\projekty\tornado\env\lib\site-packages\tornado\web.py", line 1334, in _execute
    result = yield result
  File "D:\projekty\tornado\env\lib\site-packages\tornado\gen.py", line 628, in run
    value = future.result()
  File "D:\projekty\tornado\env\lib\site-packages\tornado\concurrent.py", line 109, in result
    raise_exc_info(self._exc_info)
  File "D:\projekty\tornado\env\lib\site-packages\tornado\gen.py", line 631, in run
    yielded = self.gen.throw(*sys.exc_info())
  File "index.py", line 20, in get
    x = yield 'test'
  File "D:\projekty\tornado\env\lib\site-packages\tornado\gen.py", line 628, in run
    value = future.result()
  File "D:\projekty\tornado\env\lib\site-packages\tornado\concurrent.py", line 111, in result
    raise self._exception
BadYieldError: yielded unknown object 'test'
Run Code Online (Sandbox Code Playgroud)

码:

from tornado.ioloop import IOLoop
from tornado.web import RequestHandler, Application, url
from tornado import gen

class HelloHandler(RequestHandler):
    @gen.coroutine
    def get(self):
        x = yield 'test'
        self.render('hello.html')


def make_app():
    return Application(
        [url(r"/", HelloHandler)], 
        debug = True
    )

def main():
    app = make_app()
    app.listen(8888)
    IOLoop.instance().start()

main()
Run Code Online (Sandbox Code Playgroud)

dan*_*ano 30

正如Lutz Horn指出的那样,tornado.coroutine装饰器要求您只生成Future包含Future对象的对象或某些容器.所以试图产生一个str会引起错误.我认为你遗失的那一块是你要打电话的协程里面的任何地方yield something(),something也必须是一个协程,或者返回一个Future.例如,您可以像这样修复您的示例:

from tornado.gen import Return

class HelloHandler(RequestHandler):
    @gen.coroutine
    def get(self):
        x = yield self.do_test()
        self.render('hello.html')

    @gen.coroutine
    def do_test(self):
        raise Return('test')
        # return 'test' # Python 3.3+
Run Code Online (Sandbox Code Playgroud)

甚至这个(虽然通常你不应该这样做):

class HelloHandler(RequestHandler):
    @gen.coroutine
    def get(self):
        x = yield self.do_test()
        self.render('hello.html')

    def do_test(self):
        fut = Future()
        fut.set_result("test")
        return fut
Run Code Online (Sandbox Code Playgroud)

当然,这些都是人为的例子; 因为我们实际上并没有异步进行任何操作do_test,所以没有理由将其作为协同程序.通常你会在那里做某种异步I/O. 例如:

class HelloHandler(RequestHandler):
    @gen.coroutine
    def get(self):
        x = yield self.do_test()
        self.render('hello.html')

    @gen.coroutine
    def do_test(self):
        http_client = AsyncHTTPClient()
        out = yield http_client.fetch("someurl.com") # fetch is a coroutine
        raise Return(out.body)
        # return out.body # Python 3.3+
Run Code Online (Sandbox Code Playgroud)

  • @ user3575996使用`yield function()`将使协程的执行等到`function()`完成.但是,它不会*阻止龙卷风I/O循环,因此如果来自客户端的其他请求进入,则可以在此期间处理这些请求.但是,您不能使用`time.sleep()`来测试它,因为它是一个阻塞函数.您需要使用非阻塞版本的睡眠.有关示例,请参阅[此答案](http://stackoverflow.com/a/23876402/2073595). (2认同)