(二)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 ...
随机推荐
- Vue.js 动态为img的src赋值
在vue中动态给src赋值绑定图片会显示不出来 动态添加src被当做静态资源处理了,没有进行编译 解决方法: 1.用网络地址 把图片放在cdn或自己的服务器上,把网络地址存在imgUrl里,然后直接& ...
- Pycharm中文显示异常
pycharm2019,中文显示乱码异常,配置了encoding为utf8还是不行,需要设置备用字体 原因是某些英文字体库不支持非英文字符,无法显示 设置fallback字体 File-setting ...
- UNIX标准C - socket套接字
一.计算机网络 1.计算机网络的功能 a.数据通信 b.资源共享 c.提高系统的可靠性 d.分布式网络处理和负载均匀. 2.计算机网络的组成 1.通信子网:由网卡.线缆.集线器.中继器.交换器.路由器 ...
- JUnit——Failure与Error
(1)Failure是指测试失败(2)Error是指测试程序本身出错
- codevs2833 奇怪的梦境 x
2833 奇怪的梦境 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description Aiden陷入了一个奇怪的梦境:他被困在一个小房子中 ...
- Android 5种Toast特效
Toast是Android中用来显示显示信息的一种机制,和Dialog不一样的是,Toast是没有焦点的,而且Toast显示的时间有限,过一定的时间就会自动消失. 1.默认效果: Toast.ma ...
- python学习之路(25)
继承和多态 在OOP程序设计中,当我们定义一个class的时候,可以从某个现有的class继承,新的class称为子类(Subclass),而被继承的class称为基类.父类或超类(Base clas ...
- [POJ2942]:Knights of the Round Table(塔尖+二分图染色法)
题目传送门 题目描述 亚瑟王要在圆桌上召开骑士会议,为了不引发骑士之间的冲突,并且能够让会议的议题有令人满意的结果,每次开会前都必须对出席会议的骑士有如下要求: .相互憎恨的两个骑士不能坐在直接相邻的 ...
- webpack 自动运行,及打包 img css json 的操作 npm插件的使用方法
没有指令操作的属性生产环境,有指令操作的属于开发环境 webpack:输入指令后,便会自动开启一个浏览器 需要插件:open-browser-webpack-plugin 生产环境 想使用 node. ...
- Linux清空文本内容
测试文件:test.txt 第一种: $> test.txt 第二种: $echo "" > test.txt 第三种: $cat /dev/null > tes ...