如何在 Tornado 中将异步函数和 gen 函数包装在一起?
我的代码如下所示,错误是“Future”对象没有属性“body”。
我是否以错误的方式放置了装饰器?
import tornado.httpclient
import tornado.web
import tornado.gen
import tornado.httpserver
import tornado.ioloop
class Class1(tornado.web.RequestHandler):
@tornado.web.asynchronous
def post(self, *args, **kwargs):
url = self.get_argument('url', None)
response = self.json_fetch('POST', url, self.request.body)
self.write(response.body)
self.finish()
@tornado.gen.engine
def json_fetch(self, method, url, body=None, *args, **kwargs):
client = tornado.httpclient.AsyncHTTPClient()
headers = tornado.httputil.HTTPHeaders({"content-type": "application/json charset=utf-8"})
request = tornado.httpclient.HTTPRequest(url, method, headers, body)
yield tornado.gen.Task(client.fetch, request)
在此代码示例中不需要“异步”。 “gen.engine”已过时,请使用“coroutine”代替。现在,您通常也不需要太多使用“gen.Task”。对代码进行四处更改:
- 将“post”包裹在“coroutine”中
- “yield” self.json_fetch 的结果,而不是直接使用结果。
- 无需在协程中调用“完成”,Tornado 在协程完成时完成响应。
- 也将 json_fetch 包装在“coroutine”中。
结果:
class ClubCreateActivity(tornado.web.RequestHandler):
@tornado.gen.coroutine
def post(self, *args, **kwargs):
url = self.get_argument('url', None)
response = yield self.json_fetch('POST', url, self.request.body)
self.write(response.body)
@tornado.gen.coroutine
def json_fetch(self, method, url, body=None, *args, **kwargs):
client = tornado.httpclient.AsyncHTTPClient()
headers = tornado.httputil.HTTPHeaders({"content-type": "application/json charset=utf-8"})
request = tornado.httpclient.HTTPRequest(url, method, headers, body)
response = yield client.fetch(request)
raise gen.Return(response)
进一步阅读:
- 《Tornado 用户指南》中有关协程的部分 http://www.tornadoweb.org/en/stable/guide/coroutines.html
- Tornado 异步请求处理程序 http://www.tornadoweb.org/en/stable/guide/structure.html#asynchronous-handlers
- 我关于重构协程的文章 http://emptysqua.re/blog/refactoring-tornado-coroutines/
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)