deferred的addCallback是怎么工作的,以及相关的操作流程。 一个deferred 有一对回调链,一条处理正确的结果,一条处理错误的结果,addCallbacks 与 addCallback ,addBoth 函数则是向这对回调链里添加函数,addCallback 后,deferred 是怎么做的呢,我们看源码:
def addCallbacks(self, callback, errback=None,
callbackArgs=None, callbackKeywords=None,
errbackArgs=None, errbackKeywords=None):
"""Add a pair of callbacks (success and error) to this Deferred.
These will be executed when the ‘master‘ callback is run.
"""
assert callable(callback)
assert errback == None or callable(errback)
cbs = ((callback, callbackArgs, callbackKeywords),
(errback or (passthru), errbackArgs, errbackKeywords))
self.callbacks.append(cbs)
if self.called:
self._runCallbacks()
return self
def addCallback(self, callback, *args, **kw):
"""Convenience method for adding just a callback.
See L{addCallbacks}.
"""
return self.addCallbacks(callback, callbackArgs=args,
callbackKeywords=kw)
addCallback第二个参数是要添加的函数,第三个参数是要传递给回调函数的参数,第四个是要传递给回调函数
的关键字,然后,addCallback里调用了addCallbacks 。 我们可以看到,在deferred初始化 时,这对回调链self.callbacks 是空的
def __init__(self):
self.callbacks = []
if self.debug:
self._debugInfo = DebugInfo()
self._debugInfo.creator = traceback.format_stack()[:-1]
cbs = ((callback, callbackArgs, callbackKeywords),
(errback or (passthru), errbackArgs, errbackKeywords))
self.callbacks.append(cbs)
当调用一个回调函数时,deferred 又会怎么做呢?假设当前调用的是 callback:
def callback(self, result):
"""Run all success callbacks that have been added to this Deferred.
Each callback will have its result passed as the first
argument to the next; this way, the callbacks act as a
‘processing chain‘. Also, if the success-callback returns a Failure
or raises an Exception, processing will continue on the *error*-
callback chain.
"""
assert not isinstance(result, Deferred)
self._startRunCallbacks(result) 看作者的注释,deferred 把上一个回调函数的结果result传递给 _startRunCallbacks:
def _startRunCallbacks(self, result):
if self.called:
if self.debug:
if self._debugInfo is None:
self._debugInfo = DebugInfo()
extra = "\n" + self._debugInfo._getDebugTracebacks()
raise AlreadyCalledError(extra)
raise AlreadyCalledError
if self.debug:
if self._debugInfo is None:
self._debugInfo = DebugInfo()
self._debugInfo.invoker = traceback.format_stack()[:-2]
self.called = True
self.result = result
if self.timeoutCall:
try:
self.timeoutCall.cancel()
except:
pass
del self.timeoutCall
self._runCallbacks()
def _runCallbacks(self):
if self._runningCallbacks:
# Don‘t recursively run callbacks
return
if not self.paused:
while self.callbacks:
item = self.callbacks.pop(0)
callback, args, kw = item[
isinstance(self.result, failure.Failure)]
args = args or ()
kw = kw or {}
try:
self._runningCallbacks = True
try:
self.result = callback(self.result, *args, **kw)
finally:
self._runningCallbacks = False
if isinstance(self.result, Deferred):
# note: this will cause _runCallbacks to be called
# recursively if self.result already has a result.
# This shouldn‘t cause any problems, since there is no
# relevant state in this stack frame at this point.
# The recursive call will continue to process
# self.callbacks until it is empty, then return here,
# where there is no more work to be done, so this call
# will return as well.
self.pause()
self.result.addBoth(self._continue)
break
except:
self.result = failure.Failure()
if isinstance(self.result, failure.Failure):
self.result.cleanFailure()
if self._debugInfo is None:
self._debugInfo = DebugInfo()
self._debugInfo.failResult = self.result
else:
if self._debugInfo is not None:
self._debugInfo.failResult = None
通过作者的注释,我们可以看到,当执行完回调函数之后,
(1)若self.result 为deferred,即如果回调函数返回一个新的deferred,则当前的deferred(外部deferred)会
暂停下来,去执行新的deferred(内部deferred)里的回调函数,直到内部deferred把控制权转交给外部
deferred,如图:
看代码:
self.pause()
self.result.addBoth(self._continue) 而addBoth会调用addCallbacks, addCallbacks 则调用_runCallbacks,
def addBoth(self, callback, *args, **kw):
"""Convenience method for adding a single callable as both a callback
and an errback.
See L{addCallbacks}.
"""
return self.addCallbacks(callback, callback,
callbackArgs=args, errbackArgs=args,
callbackKeywords=kw, errbackKeywords=kw)
def addCallbacks(self, callback, errback=None,
callbackArgs=None, callbackKeywords=None,
errbackArgs=None, errbackKeywords=None):
"""Add a pair of callbacks (success and error) to this Deferred.
These will be executed when the ‘master‘ callback is run.
"""
assert callable(callback)
assert errback == None or callable(errback)
cbs = ((callback, callbackArgs, callbackKeywords),
(errback or (passthru), errbackArgs, errbackKeywords))
self.callbacks.append(cbs)
if self.called:
self._runCallbacks()
return selfcoco2d-x 中box2d选中刚体,布布扣,bubuko.com
原文:http://blog.csdn.net/tian2kong/article/details/20386425