理解 tornado.gen
转自:http://blog.xiaogaozi.org/2012/09/21/understanding-tornado-dot-gen/
理解 tornado.gen
SEP 21ST, 2012
Tornado 通过 @asynchronous decorator 来实现异步请求,但使用的时候必须将 request handler 和 callback 分离开,tornado.gen 模块可以帮助我们在一个函数里完成这两个工作。下面是官方的一个例子:
1 |
|
这里用到了两个 decorator 稍显复杂,第一个 @asynchronous 会首先被执行,它的主要工作就是将 RequestHandler 的 _auto_finish 属性置为 false,如下:
web.pydownload
1 |
|
接着就是最重要的 @gen.engine,这里充分利用了 generator 的各种特性,首先来看 @gen.engine 的实现(我删减了部分代码以简化理解):
gen.pydownload
1 |
|
局部变量 gen 代表第一段代码里的 get 函数,因为 get 包含了 yield 语句,因此成为了一个 generator。注意这里 get 并没有被执行,只是赋给了 gen。接下来是运行 Runner 对象的 run 函数。在理解 run 之前需要知道 generator 是通过调用 next() 或者 send() 来启动,启动之后会在遇到 yield 的地方 hold 住,然后将 yield 后面的语句的返回值返回给调用者,generator 此时即处于暂停运行状态,所有上下文都会保存。再次调用 next() 或 send() 便会恢复 generator 的运行,如果不再遇到 yield 语句就会抛出 StopIteration 异常。在恢复运行的同时 yield 语句本身会有返回值,如果是通过调用 next() 来恢复的,那么返回值永远是 None,而如果是通过 send() 则返回值取决于传给 send() 的参数。更多关于 generator 的说明请参考官方文档。
结合第一段的示例代码,可以想到 run 干的工作可能就是启动 generator,然后获得 gen.Task对象并调用 http_client.fetch 函数,等回调回来之后恢复 generator 的运行,最后将回调的返回值通过 send() 赋给 response。下面是我简化后的代码。
gen.pydownload
1 |
|
第 3 行检查回调是否完成,第一次运行 run 总是会返回 True。第 5 行获取回调的返回值,同样的第一次运行返回的是 None。将 None 传给 send() 启动 generator,yielded 即是 gen.Task 对象,第 12 行调用 start 开始运行我们真正需要运行的函数,对应到示例代码就是http_client.fetch 函数,同时将 Runner 的 result_callback 作为回调函数。如下:
gen.pydownload
1 |
|
在得到回调返回值之后再次调用 run,通过 get_result 获取返回值,最后将返回值返回赋给 response,继续 request handler 的代码流程。
理解 tornado.gen的更多相关文章
- tornado.gen 模块解析
转自:http://strawhatfy.github.io/2015/07/22/Tornado.gen/ 引言 注:正文中引用的 Tornado 代码除特别说明外,都默认引用自 Tornado 4 ...
- 深入理解Tornado——一个异步web服务器
本人的第一次翻译,转载请注明出处:http://www.cnblogs.com/yiwenshengmei/archive/2011/06/08/understanding_tornado.html原 ...
- Tornado @tornado.gen.coroutine 与 yield
在使用 Tornado 的过程中产生了以下疑问: 什么时候需要给函数增加 @tornado.gen.coroutine 什么时候调用函数需要 yield @tornado.gen.coroutine ...
- Python之路(四十一):通过项目来深入理解tornado
Tornado之路 引子 与其感慨路难行,不如马上出发 目录 通过项目来深入理解tornado(一):tornado基础回顾 通过项目来深入理解tornado(二):AsyncHttpClient ...
- 如何捕捉@tornado.gen.coroutine里的异常
from tornado import gen from tornado.ioloop import IOLoop @gen.coroutine def throw(a,b): try: a/b ra ...
- 理解tornado
计算密集型:多进程 IO密集型:多线程 能产生IO阻塞的情况很多,比如网络通讯.磁盘读写.当发生阻塞时,CPU是闲置的,此时如果就一个线程就没法处理其他事情了. 所以对于含有IO阻塞的环境,多线程 ...
- tornado.gen.coroutine-协程
http://blog.csdn.net/seeground/article/details/49488281
- 深入理解yield(三):yield与基于Tornado的异步回调
转自:http://beginman.cn/python/2015/04/06/yield-via-Tornado/ 作者:BeginMan 版权声明:本文版权归作者所有,欢迎转载,但未经作者同意必须 ...
- tornado 杂记
一.建立一个简单的 hello world 网页 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 import tornado.iolo ...
随机推荐
- SWIFT中获取配置文件路径的方法
在项目中有时候要添加一些配置文件然后在程序中读取相应的配置信息,以下为本人整理的获取项目配置文件(.plist)路径的方法: 1.获取沙盒路径后再APPEND配置文件 func documentsDi ...
- python可视化爬虫实现“京东试用”批量申请
介绍: 环境:chromedriver 2.41.578700+ selenuim3.14.0 过程: 1.打开京东主页 2.登录京东 3.打开京东试用页面 4.获取商品列表 5.自动申请试用(该商品 ...
- 2N7002
就相当于一个开关,当G>S的一定电压就导通,若没有达到就没有导通. 并且注意的是D脚不能直接接电压,中间要接一个电阻. 这用是G输入,S接地,D输出. 跟三极管差不多.分N和P
- M端错误提醒 -- pop 使用
JS: window.pop = {/*alert提示框 *@param title 提示的标题 *@param desc 提示的描述 *@param btnNum 按钮的数量,假如为1,则无视e2, ...
- java安装教程及环境配置
下载JDK(网上有很多,可以百度) 首先在非系统盘(系统盘通常是C盘)中,新建一个Java(可以是其他名称,必须是英文且名称中没有空格)文件夹,并在这个文件夹中创建JDK,JRE两个文件夹. 双击已下 ...
- hdu2073-2078
hdu2073 数学 #include<stdio.h> #include<math.h> double len(double x){ )*(x+)); } int main( ...
- Tomcat:Several ports are already in use问题
Several ports (8005, 8080, 8009) required by Tomcat v6.0 Server at localhost are already in use. The ...
- day41 python【事物 】【数据库锁】
MySQL[五] [事物 ][数据库锁] 1.数据库事物 1. 什么是事务 事务是应用程序中一系列严密的操作,所有操作必须成功完成,否则在每个操作中所作的所有更改都会被撤消.也就是事务具有原子性 ...
- git server side hook 试用
git 的hook 是一个很方便的功能,我们可以使用hook 做好多处理,比如client side hook 进行 提交格式校验,server side 进行ci/cd 处理 测试使用docker- ...
- 01.ubuntu14.04安装HI3518EV200 SDK的过程
转载,侵删 1.海思SDK安装编译 Hi3518EV200_SDK是基于Hi3518EV200_DMEB的软件开发包,包含了在Linux相关应用开发时使用的各种工具及其源代码,是用户开发中最基本的软件 ...