(二)inlineCallbacks,同步方式写异步代码
一、 上篇提到了用defered对象注册回调的方式,来处理异步操作,这样大家都知道,实际情况代码很难搞的。因为当业务逻辑复杂后,这边一个异步操作,我们注册一个回调,代码跳到A地方,A里面也有异步操作,注册回调,然后跳到B,自己看起来都晕,维护起来不方便,不好读也不好排错,这时候,如果有简单的方式就更好了,能提高书写效率。
类似于tornado的gen.coroutine,我们可以用@inlineCallbacks装饰器,配合yield关键字,将代码结构变成同步的。
二、在@inlineCallbacks装饰的情况下,先看这几点:
1. deferred对象的结果,也就是异步操作完成后的返回结果,这个返回结果正常是传递给了callback,我们通过yield deferred可以拿到
2. 下层callback的返回值即作为上层callback的参数,直至最外层。
# coding:utf-8 import time from twisted.internet import defer, reactor
from twisted.internet.defer import inlineCallbacks, returnValue class deferTester():
def __init__(self):
self.d = defer.Deferred() #模拟耗时操作
@inlineCallbacks
def work(self):
print "[%s] 模拟耗时网络IO, 等待3秒" % nowtime()
time.sleep(3)
retult = yield('haha')#非延迟对象会立即返回
print "[%s] result = "%nowtime(),retult
reactor.callLater(2, self.d.callback, retult)
self.d.addCallback(self.first_call)
self.d.addCallback(self.second_call) def first_call(self, x):
print "[%s] inner调用,接收参数 = " % nowtime(), x
return 5 #返回的值作为之后callback的参数 def second_call(self, x):
print "[%s] nest调用,接收参数 = " % nowtime(), x def stop():
reactor.stop()
print "[%s] 停止reactor"%nowtime() def nowtime():
return time.strftime('%Y-%m-%d,%X', time.localtime()) if __name__ == '__main__':
print "[%s] 开始测试 "%nowtime()
tester = deferTester()
reactor.callWhenRunning(tester.work)#reactor调用耗时任务
print "[%s] 启动reactor "%nowtime()
reactor.callLater(8, stop) #5秒后停止reactor线程
reactor.run()
打印结果为:
[2018-10-25,18:13:13] 开始测试
[2018-10-25,18:13:13] 启动reactor
[2018-10-25,18:13:13] 模拟耗时网络IO, 等待3秒
[2018-10-25,18:13:16] result = haha
[2018-10-25,18:13:18] first_call,接收参数 = haha
[2018-10-25,18:13:18] second_call,接收参数 = 5
[2018-10-25,18:13:21] 停止reactor
可以看出,first_call的返回值5作为second_call的入参
我们稍微修改下测试类如下:
#模拟耗时操作
@inlineCallbacks
def work(self):
print "[%s] 模拟耗时网络IO, 等待3秒" % nowtime()
time.sleep(3)
retult = yield('haha')#非延迟对象会立即返回
print "[%s] result = "%nowtime(),retult
reactor.callLater(2, self.d.callback, retult)
self.d.addCallback(self.inner_work)
res = yield self.d #此时d对象调用inner_work,返回结果为5
print "[%s] res = "%nowtime(),res @inlineCallbacks
def inner_work(self, x):
print "[%s] inner调用,接收参数 = " % nowtime(), x
yield returnValue(5) #生成器中不能用return返回结果
结果为:
[2018-10-25,18:15:05] 开始测试
[2018-10-25,18:15:05] 启动reactor
[2018-10-25,18:15:05] 模拟耗时网络IO, 等待3秒
[2018-10-25,18:15:08] result = haha
[2018-10-25,18:15:10] inner调用,接收参数 = haha
[2018-10-25,18:15:10] res = 5
[2018-10-25,18:15:13] 停止reactor
如果用了inlineCallback, 返回的是一个生成器,此时不能用简单的return,twisted有returnValue可以使用
(二)inlineCallbacks,同步方式写异步代码的更多相关文章
- boost::ASIO的同步方式和异步方式
http://blog.csdn.net/zhuky/article/details/5364574 http://blog.csdn.net/zhuky/article/details/536468 ...
- 使用HTTP的同步方式还是异步方式?
同步与异步 同步:提交请求->等待服务器处理->处理完毕返回 这个期间客户端浏览器不能干任何事 异步: 请求通过事件触发->服务器处理(这是浏览器仍然可以作其他事情)->处理完 ...
- iOS网络编程--NSConnection的同步连接与异步连接
// // ZFViewController.m // 0628-表单验证 // // Created by zfan on 14-6-28. // Copyright (c) 2014年 zfan. ...
- 无感知的用同步的代码编写方式达到异步IO的效果和性能,避免了传统异步回调所带来的离散的代码逻辑和陷入多层回调中导致代码无法维护
golang/goroutine 和 swoole/coroutine 协程性能测试对比 - Go语言中文网 - Golang中文社区 https://studygolang.com/articles ...
- [每日一题]面试官问:Async/Await 如何通过同步的方式实现异步?
关注「松宝写代码」,精选好文,每日一题 时间永远是自己的 每分每秒也都是为自己的将来铺垫和增值 作者:saucxs | songEagle 一.前言 2020.12.23 日刚立的 flag,每日一 ...
- node.js的作用、回调、同步异步代码、事件循环
http://www.nodeclass.com/articles/39274 一.node.js的作用 I/O的意义,(I/O是输入/输出的简写,如:键盘敲入文本,输入,屏幕上看到文本显示输出.鼠标 ...
- 【WP8】同步执行异步代码
微软的StorageFile只支持异步的方式进行文件操作,我之前也封装过一个StorageHelper,但是当所有的方法都是异步的时候也带来一些问题 1.比如我们不能在构造函数调用异步代码(等待), ...
- 将 async/await 异步代码转换为安全的不会死锁的同步代码
在 async/await 异步模型(即 TAP Task-based Asynchronous Pattern)出现以前,有大量的同步代码存在于代码库中,以至于这些代码全部迁移到 async/awa ...
- redux本来是同步的为什么它能执行异步代码(chunk)实现原理是什么 中间件的实现原理是什么
我们用redux执行同步的时候,都是先发起一个dispatch(actionCreator()) 1.先在actionCreator()中生成一个action对象. 2.由dispatch方法将act ...
随机推荐
- k-means伪代码
1.初始化k个簇中心. 2.更新所有样本点簇归属:样本点到哪个簇中心点最近就属于哪个簇. 3.重新计算每个簇的中心点(直到簇中心点不再变化或达到更新最大次数) #k-means伪代码 import n ...
- 《Head First 软件开发》阅读二
项目计划:为成功而筹划 每段伟大的代码始于伟大的计划. 客户现在就要他们的软件,可是开发需要的时间远远超过客户要求时间.我们需要实际解决方法:由客户确定优先级,与客户一起确定优先级顺序,开发出Mile ...
- [LOJ 6704] 健身计划
问题描述 九条可怜是一个肥胖的女孩. 她最近长胖了,她想要通过健身达到减肥的目的,于是她决定每天做n次仰卧起坐以达到健身的目的. 她可以将这n次动作分为若干组完成,每一次完成ai次仰卧起坐,每做完一次 ...
- 正则化方法L1 L2
转载:http://blog.csdn.net/u012162613/article/details/44261657(请移步原文) 正则化方法:防止过拟合,提高泛化能力 在训练数据不够多时,或者ov ...
- zabbix 磁盘自动发现脚本
##需要在zabbix界面配置宏变量===>正则来匹配磁盘 disk_discovery.sh ———————————————————————————————————————————————— ...
- sqljob
http://blog.csdn.net/sinat_16998945/article/details/52586687
- pythonCSV模块
在爬虫过后会取得很多信息! 将信息存起来方法还很多中!今天提一下CSV模块 导入模块 import csv 这里先写个列表 rows = [['zhangsan',20],['lisi',22],[' ...
- Linux小记 -- [已解决]Failed to connect to https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings
问题描述 操作系统:Ubuntu Server 18.04 LTS Ubuntu每次启动时产生如下motd(message of today)输出 Failed to connect to https ...
- java8 stream初试,map排序,list去重,统计重复元素个数,获取map的key集合和value集合
//定义一个100元素的集合,包含A-Z List<String> list = new LinkedList<>(); for (int i =0;i<100;i++) ...
- 六、RF中断言关键字使用详解
1.should be equal 和should be not equal :比较两个值相等或不相等 2.should start with 和should not start with :判 ...