Deferred
Deferred是Twisted中处理回调的一种抽象机制。一个Deferred有一对回调链,一个处理正确的结果,另一个处理异常结果。我们可以通过向其中添加callback
和errback
回调来使Deferred响应正确结果或者异常结果。
以下是一个只有一层回调的Deferred示例。
from twisted.internet.defer import Deferred
from twisted.python.failure import Failure
def success(res):
print('A success chain')
return res
def err_process(err):
print('A Error occurred')
d = Deferred()
d.addCallbacks(success, err_process)
d.callback('success') # 调用处理正确结果的回调
d.errback(Failure(Exception('Some error'))) # 调用处理错误结果的回调,这里手工建立Failure对象
d.errback(Esception('Some error')) # 调用处理错误结果的回调,Deferred会将Exception对象自动转换为Failure对象
一个Deferred
对象只允许被激活一次,也就是只允许调用一次.callback()
方法。这是因为多次激活会导致多个回调同时出现,
下面再向Deferred
中添加一层回调,并且跟Reactor结合起来。
from twisted.internet.defer import Deferred
def success(res):
print('A success chain')
return res
def err_process(err):
print('A Error occurred')
def done(_):
from twisted.internet import reactor
reactor.stop()
d = Deferred()
d.addCallbacks(success, err_process)
d.addBoth(done) # 将回调同时添加到两条回调链上
from twisted.internet import reactor
reactor.callWhenRunning(d.callback, 'Success calling') # 当Reactor启动时调用指定函数,并传递给定的参数
reator.run()
在不使用Deferred时,重构异步函数相当困难,但是借助Deferred,可以通过修改回调链来重构应用。
Deferred提供了以下四个方法来将回调函数添加到回调链中。
\begin{itemize}
.addCallbacks(callback, errback)
,同时添加一对callback
和errback
。.addCallback(callback)
,添加一个callback
和一个直接返回第一个参数的直通函数。.addErrback(errback)
,添加一个errback
和一个直通函数。.addBoth(function)
,将同一个回调函数同时添加到两条回调链中。 \end{itemize}
这里要注意的一个问题就是:在一个Deferred中,callback
和errback
总是成对出现的,即便是仅添加一个callback
或者errback
,Deferred也会自动向另一条回调链中添加一个虚设的函数。
Deferred可以嵌套,可以在一个回调函数中返回一个Deferred,这样外层的Deferred会等待内部的Deferred激活并返回后继续执行。