(二)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 ...
随机推荐
- 12. ClustrixDB 为容错和可用性分配磁盘空间
集群必须包含足够的空闲磁盘空间,以便从节点或区域故障中自动恢复.要计算在发生故障后仍然允许ClustrixDB完全重新保护数据的情况下可以使用的最大磁盘空间量,可以使用以下公式: 最大磁盘利用率% = ...
- 两个i标签之间有缝隙
给i标签的父元素设置font-size:0:
- html abbr标签 语法
html abbr标签 语法 作用:标记一个缩写 大理石平台 说明:<abbr> 标签指示简称或缩写,比如 "WWW" 或 "NATO".通过对缩写 ...
- JUnit——Failure与Error
(1)Failure是指测试失败(2)Error是指测试程序本身出错
- bash配置文件
bash的配置文件 一.shell的两种登录方式: 1.交互式登录: (1)直接通过终端输入账号密码登录 (2)使用"su - UserName" 切换的用户 执行顺序:/etc/ ...
- [HDU3072]:Intelligence System(塔尖+贪心)
题目传送门 题目描述 “这一切都是命运石之门的选择.”试图研制时间机器的机关SERN截获了中二科学家伦太郎发往过去的一条短 信,并由此得知了伦太郎制作出了电话微波炉(仮).为了掌握时间机器的技术,SE ...
- kubernetes master 更换ip(单节点)
问题分析 master ip地址变更以后,我们首先应该检查以下内容: /etc/kubernetes/manifests下面的config配置文件,替换里面对应的ip 相关的证书文件 客户端文件 解决 ...
- Java的LinkedList底层源码分析
首先我们先说一下,源码里可以看出此类不仅仅用双向链表实现了队列数据结构的功能,还提供了链表数据结构的功能.
- Zookeeper集群及配置
特别提示:本人博客部分有参考网络其他博客,但均是本人亲手编写过并验证通过.如发现博客有错误,请及时提出以免误导其他人,谢谢!欢迎转载,但记得标明文章出处:http://www.cnblogs.com/ ...
- legend3---用Homestead配置后报错“No input file specified.”
legend3---用Homestead配置后报错“No input file specified.” 一.总结 一句话总结: 自己项目上传到github的时候多增加了一层legend3的github ...