如何在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)
答案 0 :(得分:2)
此代码示例中不需要“异步”。 “gen.engine”已经过时,请改用“coroutine”。这些天你通常不需要使用“gen.Task”。对代码进行四处更改:
结果:
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)
进一步阅读:
答案 1 :(得分:1)
龙卷风官方文档中推荐的方法是同时使用 @ tornado.gen.coroutine 和 yield 。
如果要同时使用异步和yield的优势,则应嵌套 @ tornado.web.asynchronous 装饰器,然后嵌入 @ tornado.gen.engine 强>
答案 2 :(得分:0)
有关“异步调用自己的函数”的文档,但没有额外的外部回调函数 - Asynchronous and non-Blocking I/O
您可以像这样制作 json_fetch :
from tornado.concurrent import Future
def json_fetch(self, method, url, body=None, *args, **kwargs):
http_client = tornado.httpclient.AsyncHTTPClient()
my_future = Future()
fetch_future = http_client.fetch(url)
fetch_future.add_done_callback(
lambda f: my_future.set_result(f.result()))
return my_future
或者像这样(来自A. Jesse Jiryu Davis的回答):
from tornado import gen
@gen.coroutine
def json_fetch(self, method, url, body=None, *args, **kwargs):
http_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 http_client.fetch(request)
raise gen.Return(response)
*在json_fetch的“gen.coroutine”和“yield”调用中包装“post”。
**“仅为Python2提升gen.Return(响应)”,在Python3.3及更高版本中你应该写“返回响应”。
感谢A. Jesse Jiryu Davis提供链接“Tornado异步请求处理程序”,在那里找到了“异步和非阻塞I / O”。