Wonderjar's Blog

tornado4中@gen.coroutine

2018-07-26

在用python2.7,tornado4.5,想要把一些异步http请求封装成service给上层调用,查了好久资料,记下结论

1
2
3
4
5

# controller层
@gen.coroutine
def get(self):
result = xx_service.doSomething()
1
2
3
4
5
6
# service层
@gen.coroutine
def doSomething(self):
resp = yield http.fetch('http://abc')
res = json.loads(resp.body.decode(encoding='utf8'))
raise gen.Return(res)

被@gen.coroutine修饰的函数返回Future,被yield调用时,会反复调用直到raise gen.Return(result),因为调用者也使用了yield,一般也需要调用者的函数也被@gen.coroutine修饰

后来遇到一种情况,非要从没被@gen.coroutine修饰的函数调用一个被@gen.coroutine修饰的函数,后来找到一种办法,

1
2
3
4
5
6
7
8
9
10
from tornado.ioloop import IOLoop

def sync(fn):
def wrapped(*args, **kwargs):
return IOLoop.instance().run_sync(lambda: fn(*args, **kwargs))

return wrapped

sync_fn = sync(my_method)
result = sync_fn('Hello')
Tags: Python