繁体   English   中英

在RequestHandler写入的情况下,Yield和Await的行为不同(Tornado Web Framework)

[英]Different behaviour for Yield and Await in case of RequestHandler write ( Tornado Web Framework )

我使用RequestHandler使用Tornado Web框架进行基于Web的调用。 以前我使用的是支持@ gen.coroutine和yield的Tornado Version 5.1.1。

我正在将我的龙卷风版本移动到6.0.2并且最近因为他们已经折旧了装饰协同程序所以我将我的代码移动到本地协同程序。

但我注意到装饰的协同程序和本地协同程序之间的不同行为。

示例

  • main.py:
import tornado.ioloop as ioloop
import tornado.web as web
from RequestHandler import MainHandler

def main():
    application = web.Application([
        (r"/", MainHandler),
    ])
    application.listen(8080)

    ioloop.IOLoop.current().start()

if __name__ == '__main__':
    main()
  • MainHandler(龙卷风5.0.2版)
import tornado.web
import tornado.gen

class MainHandler(tornado.web.RequestHandler):
    def initialize(self):
        self.data = "Hello World"

    @gen.coroutine
    def get(self):
        yield self.write(self.data)

    @gen.coroutine
    def post(self):
        yield self.write(self.data)

  • MainHandler(版本6.0.2)
import tornado.web

class MainHandler(tornado.web.RequestHandler):
    def initialize(self):
        self.data = "Hello World"

    async def get(self):
        self.write(self.data)

    async def post(self):
        self.write(self.data)

在装饰协同程序的情况下,它工作正常,但当我使它async-await和当我添加await for self.write()我开始收到错误

错误:

ERROR:tornado.application:Uncaught exception GET / (::1)
HTTPServerRequest(protocol='http', host='localhost:8080', method='GET', uri='/', version='HTTP/1.1', remote_ip='::1')
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/tornado/web.py", line 1699, in _execute
    result = await result
  File "/Users/sharvin/Desktop/Personal_Projects/All_Tornado_Projects/1. Tornado_Basics/MainHandler.py", line 8, in get
    await self.write(self.data)
TypeError: object NoneType can't be used in 'await' expression
ERROR:tornado.access:500 GET / (::1) 3.45ms

我使用self.write在网络上写入数据。

我检查了Tornado文档并根据RequestHandler的write方法不支持Future对象:

RequestHandler.write(chunk: Union[str, bytes, dict]) → None

根据文档,没有必要为self.write添加await。 我很困惑这会使self.write在网络上异步而不添加等待吗?

WebSocketHandler.close()方法也是如此。

write()实际上并没有将数据写入网络。 它只将数据写入内存缓冲区。 此操作非常快,不需要异步。

为了实际将数据发送到网络,还有另一种名为flush()方法,可以等待/产生。

flush()在你要以块或循环方式返回数据的情况下非常有用:

while True:
    self.write("some data") # writes to buffer
    await self.flush() # writes to network

如果您一次性返回所有数据,则不必担心调用flush() 当处理程序退出时,Tornado会自动为您执行此操作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM