tornado5.0+async+await

时间:2019-12-17
本文章向大家介绍tornado5.0+async+await,主要包括tornado5.0+async+await使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

不使用数据库的情况下实现异步

  • 使用gen.sleep()模拟阻塞

    • 使用gen.sleep(time) 而不是time.sleep(),time.sleep()阻塞整个进程,看gen.sleep()源码,sleep方法返回了一个tuture对象,不是处于阻塞状态而是等待time时间后调用callback函数,在等待的过程中,将控制权交回IOLoop,IOLoop可以处理其他请求
    def sleep(duration):
        f = _create_future()
        #  callback匿名函数加入IOLoop循环, future_set_result_unless_cancelled方法完成future的填充
        IOLoop.current().call_later(duration,
                            lambda: future_set_result_unless_cancelled(f, None))
        return f
    
    def call_later(self, delay, callback, *args, **kwargs):
        # 设置多少时间后执行callback
        return self.call_at(self.time() + delay, callback, *args, **kwargs)
    
    def future_set_result_unless_cancelled(future, value):
        if not future.cancelled():
            # 执行future.set_result(),完成这个future的填充
            future.set_result(value)
  • 如下代码直接复制粘贴运行,在调用http://127.0.0.1:80/blocking 的时候发现正在等待,同时调用/index接口可以直接拿到返回值,说明两个接口互不阻塞

``` 
from tornado.web import RequestHandler
from tornado import gen
import tornado.ioloop

class IndexHandler(RequestHandler):
    def get(self):
        self.write('this is index')

class BlockingHandler(RequestHandler):
    async def get(self):
        result = await self.dosomething()
        self.write(result)

    async def dosomething(self):
        # 如果是其他处理函数或者逻辑,要保证函数是协程
        await gen.sleep(20)
        return 'block end'

app = tornado.web.Application([
    (r"/index", IndexHandler),
    (r"/blocking", BlockingHandler)
])
if __name__ == "__main__":
    app.listen(80)
    tornado.ioloop.IOLoop.instance().start()
```

  • 使用tornado gen模块下的coroutine装饰器+yield关键字,或者async+await关键字都可实现协程,python3.5以后推荐使用原生协程,yield关键字主要还是在生成器的时候使用

原文地址:https://www.cnblogs.com/Victor-ZH/p/12054076.html