(二)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 ...
随机推荐
- Modbus软件开发实战指南 之 开发自己的Modbus Poll工具 - 3
Modbus-RTU 一.数据分析 两个设备(单片机)通讯,用的是Modbus协议. 在单片机中拿出一部分内存(RAM)进行两个设备通讯,例如: 说明: OX[20] 代表是 ...
- Gitlab+Jenkins+Docker实现net core持续集成
前言 在项目中使用这一套自动集成的体系之后,一直想找个时间总结出来,用于自己记录也打算将自己的所得分享给园友们,不经常写文章,可能会有错误的地方,希望各位不吝指正,我会及时的改正并表示感谢,希望大家能 ...
- Codeforces Round #568 (Div. 2) D. Extra Element
链接: https://codeforces.com/contest/1185/problem/D 题意: A sequence a1,a2,-,ak is called an arithmetic ...
- Eclipse修改背景颜色(豆沙绿)
操作界面默认颜色为白色.对于我们长期使用电脑编程的人来说,白色很刺激我们的眼睛,所以我经常会改变workspace的背景色,使眼睛舒服一些.设置方法如下: 1.打开window->Prefere ...
- 恩友歌 What a friend we've found 歌词
Verse 1 何等恩友仁慈救主 负我罪孽担我忧 何等权利能将万事 来到耶稣座前求 多少平安我们坐失 多少痛苦冤枉受 都是因为未将万事 来到耶稣座前求 Verse 2 我们有无试探 ...
- 【知识】location.search获取中文时候会被编码成一串字符
[转码] 例如:case.html?id='这个是页面的标题' 当想要使用location.search获取?id='这个是页面的标题'的时候,包含的中文会被编码成一串字符串. 所以我们需要进行解码, ...
- 157. [USACO Nov07] 奶牛跨栏(第三次考试大整理)
157. [USACO Nov07] 奶牛跨栏 输入文件:hurdles.in 输出文件:hurdles.out 简单对比 时间限制:1 s 内存限制:128 MB 译 by CmYkRg ...
- scrapy项目2:爬取智联招聘的金融类高端岗位(spider类)
---恢复内容开始--- 今天我们来爬取一下智联招聘上金融行业薪酬在50-100万的职位. 第一步:解析解析网页 当我们依次点击下边的索引页面是,发现url的规律如下: 第1页:http://www. ...
- oracle SQL查询number字段精度丢失之解决方法
解决办法: -- 3.3:表示原始数据 --fm9999999990.0000:表示保留到小数点后4位,若不存在则用0补位. ),'fm9999999990.0000') as demo from d ...
- [design pattern](7) Singleton
前言 上面的章节中,我们介绍了工厂模式,它是创建型模式的一种.本章我们将会介绍 单例模式 ,它也是创建型模式的一种.单例模式是我们比较常用的一个设计模式,也是最简单的一种设计模式. 单例模式 介绍:确 ...