我正在使用tornado
装饰器处理带有GET请求的异步协同程序的Python3 @gen.coroutine
Web服务器。我想从库中使用这个函数:
@gen.coroutine
def foo(x):
yield do_something(x)
这很简单:
@gen.coroutine
def get(self):
x = self.some_parameter
yield response(foo(x))
现在假设有多个相同类型的函数foo1
,foo2
等。我希望在...foo3(foo2(foo1(x).result()).result())...
方法中执行类似yield
和response(foo(x))
的操作,而不仅仅是get
。
我认为使用reduce
和result
方法会很容易。但是,由于tornado
的工作原理,我无法强制foo
使用result
方法返回某些内容。这意味着yield reduce(...)
会出错:“DummyFuture不支持阻止结果”。从SO和其他地方的其他答案中,我知道我将不得不使用IOLoop
或其他我不太了解的东西,并且......
...我的问题是,我怎样才能避免评估来自{{foo
和yield
get
和 var gridArray: [[UIView]] = []
for y in 0 ... 10 {
var rowArray: [UIView] = []
for x in 0 ... 10 {
let cell : UIView!
cell = UIView(frame: CGRect(x:10, y:10, width:10, height:10))
self.view?.addSubview(cell)
rowArray.append(cell)
}
gridArray.append(rowArray)
}
未评估的大块1}}方法?
编辑:这不是this question的重复,因为我想:1。嵌套很多功能,然后2.尝试不立即评估
答案 0 :(得分:1)
在龙卷风中,你必须在协程中yield
一个未来才能获得结果。查看Tornado's coroutine guide。
你可以写一个协程的reducer。它运行每个协同程序以获取Future,使用Future调用yield
来获得结果,然后在该结果上运行下一个协同程序:
from tornado.ioloop import IOLoop
from tornado import gen
@gen.coroutine
def f(x):
# Just to prove we're really a coroutine.
yield gen.sleep(1)
return x * 2
@gen.coroutine
def g(x):
return x + 1
@gen.coroutine
def h():
return 10
@gen.coroutine
def coreduce(*funcs):
# Start by calling last function in list.
result = yield funcs[-1]()
# Call remaining functions.
for func in reversed(funcs[:-1]):
result = yield func(result)
return result
# Wrap in lambda to satisfy your requirement, to
# NOT evaluate immediately.
latent_result = lambda: coreduce(f, g, h)
final_result = IOLoop.current().run_sync(latent_result)
print(final_result)