Twisted 延迟调用
延迟(defer)是twisted框架中实现异步的编程体系,使程序设计可以采用事件驱动的机制
1、基本使用
defer可以看作一个管理回调函数的对象,可以向该对象添加需要的回调函数同时也可以指定该组函数何时被调用
from twisted.internet import reactor,defer from twisted.python import failure import sys d = defer.Deferred() # 定义defer实例 #####################函数添加阶段 def printSquare(d): # 正常处理函数 print('square of %d id %d '% (d,d*d)) def processError(f): print('error when process') d.addCallback(printSquare) # 添加正常处理回调函数 d.addErrback(processError) # 添加错误处理回调函数 ################defer调用阶段 if sys.argv[1] =='call_error': f= failure.Failure(Exception('my exception')) d.errback(f) # 调用错误处理函数 else: d.callback(4) # 调用正常处理函数
注:一个defer对象在添加完成回调函数过程后,只能由callback或者errback调用一次,如果嗲用两次,将会抛出异常
一个defer对象可以被赋予多个正常或错误的回调函数,这样形成的函数链将会按顺序调用执行
from twisted.internet import reactor,defer from twisted.python import failure import sys d = defer.Deferred() # 定义defer实例 #####################函数添加阶段 def printSquare(d): # 正常处理函数 print('square of %d id %d '% (d,d*d)) return d def processError(f): print('error when process') def printTwice(d): print('Twice of %d is %d'%(d,2*d)) return d d.addCallback(printSquare) # 添加正常处理回调函数 d.addErrback(processError) # 添加错误处理回调函数 d.addCallback(printTwice) # 添加第二个正常处理回调函数 ################defer调用阶段 d.callback(5)
2、defer对象详解
- addCallback(self,callback,*args,**kwargs)
回调函数中必须有参数(单个,多个,默认值),不能为空;回调函数被调用时,回调函数第一个参数是defer函数链中前一个正常处理函数的返回结果,其后的参数是 addCallback()时指定的args和kw参数
- addErrback(self,errback,*args,**kwargs)
和正常回调函数类似,当函数被调用时第一个参数是failure.Failure(Exception('my exception'))的实例,用于说明错误情况
- addBoth(self,callback,*args,**kwargs)
将同一个回调函数同时作为正常处理函数和错误处理函数添加到defer对象中
- chainDeferred(self,d)
Defer对象链接函数用于将另一个defer对象的处理函数和错误处理函数添加到本defer对象中,本函数具有单向性
D1 = defer.Deferred() D2 = defer.Deferred() D1.chainDeferred(D2)
- callback(self,result)
调用正常处理函数连,result是传递给第一个正常处理回调函数的参数
- errback(self,fail=None)
调用错误处理函数链,fail是传递给第一个错误处理回调函数的参数
- pause(self)和unpause(self)
为Defer对象调用链的暂停和继续pause函数用于暂停一个defer对象中函数链的调用,直到unpause函数被调用后继续
3、defer回调函数链的调用流程
4、结合defer和reactor
将defer对象和reactor的延时调用机制结合在一起,就可以开发出功能强大的异步调用函数
from twisted.internet import reactor,defer #####################函数添加阶段 def printSquare(d): # 正常处理函数 print('square of %d id %d '% (d,d*d)) return d def printTwice(d): print('Twice of %d is %d'%(d,2*d)) return d def makeDefer(): d = defer.Deferred() # 定义defer实例 d.addCallback(printSquare) # 添加正常处理回调函数 d.addCallback(printTwice) # 添加第二个正常处理回调函数 reactor.callLater(2,d.callback,5) # 配置延时2秒调用 ################defer调用阶段 makeDefer() reactor.run() #挂起运行
reactor.callLater(delay,callable,*args,**kwargs)
第一个参数为延迟时间,之后参数为被调用的函数名及其参数
利用callLater函数,可以实现定时退出twisted消息循环:
from twisted.internet import reactor,defer reactor.callLater(4,reactor.stop) # 运行4秒后调用reactor.stop reactor.run() print('程序退出')