[英]Tornado coroutine
I am trying to learn tornado coroutines, but I have error using below code. 我正在尝试学习龙卷风协程,但是使用以下代码却出错。
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'
Code: 码:
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()
As Lutz Horn pointed out, the tornado.coroutine
decorator requires that you yield only Future
objects or certain containers containing Future
objects. 正如Lutz Horn指出的那样,
tornado.coroutine
装饰器仅要求您产生Future
对象或某些包含Future
对象的容器。 So trying to yield a str
will raise an error. 因此,尝试产生
str
会引发错误。 I think the piece you're missing is that any place inside of a coroutine where you want to call yield something()
, something
must either also be a coroutine, or return a Future
. 我认为您缺少的部分是协程内部任何要调用
yield something()
, something
也必须是协程,或返回Future
。 For example, you could fix your example like this: 例如,您可以这样修改示例:
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+
Or even this (though generally you shouldn't do it this way): 甚至是这样(尽管通常您不应该这样):
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
Of course, these are contrived examples; 当然,这些是人为的例子。 since we're not actually doing anything asynchronous in
do_test
, there's no reason to make it a coroutine. 由于我们实际上并没有在
do_test
执行任何异步do_test
,因此没有理由使其成为协程。 Normally you'd be doing some kind of asynchronous I/O in there. 通常,您将在其中执行某种异步I / O。 For example:
例如:
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+
From the documentation : 从文档中 :
Most asynchronous functions in Tornado return a
Future
;Tornado中的大多数异步函数都返回
Future
; yielding this object returns its result.产生此对象将返回其结果。
You can also
yield a list or dict of Futures
, which will be started at the same time and run in parallel;您还可以
yield a list or dict of Futures
,它们将同时启动并并行运行; a list or dict of results will be returned when they are all finished:完成后将返回结果列表或命令:
The string "test"
is not a Future
. 字符串
"test"
不是Future
。 Try to yield one. 尝试屈服一个。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.