我来自Twisted
/ Klein
。我安静地来,并要求Tornado
帮助。我正在调查龙卷风以及它对异步的看法与Twisted的区别。 Twisted有类似于gen.coroutine
的{{3}},我可以像这样编写异步代码:
kleinsample.py
@app.route('/endpoint/<int:n>')
@defer.inlineCallbacks
def myRoute(request, n):
jsonlist = []
for i in range(n):
yield jsonlist.append({'id': i})
return json.dumps(jsonlist)
curl cmd:
curl localhost:9000/json/2000
此端点将创建一个n
个元素的JSON字符串。 n
可能很小或很大。我能够在Twisted中将其分解,以便事件循环不会使用yield
阻止。现在,我试图将其转换为龙卷风:
tornadosample.py
async def get(self, n):
jsonlist = []
for i in range(n):
await gen.Task(jsonlist.append, {'id': i}) # exception here
self.write(json.dumps(jsonlist))
追溯:
TypeError: append() takes no keyword arguments
我很困惑我应该做些什么来正确迭代循环中的每个元素,以便事件循环不被阻止。有没有人知道“龙卷风”的做法?
答案 0 :(得分:1)
您不能也不能等待jobs
,因为它不是协程并且不会返回Future。如果你想偶尔屈服以允许其他协同程序继续使用Tornado的事件循环,等待gen.moment。
append
那就是说,除非这个功能非常 CPU密集型并且需要几百毫秒或更长时间才能完成,你可能最好不要一次完成所有计算而不是多次通过函数返回之前的事件循环。
答案 1 :(得分:1)
list.append()
会返回None
,因此您的Klein示例看起来像是会产生一些对象,这有点误导。这相当于jsonlist.append(...); yield
两个单独的语句。龙卷风相当于await gen.moment
代替裸yield
。
另请注意,在Tornado中,处理程序通过调用self.write()
而不是返回值来生成响应,因此return
语句应为self.write(json.dumps(jsonlist))
。
答案 2 :(得分:0)