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 self
coco2d-x 中box2d选中刚体,布布扣,bubuko.com
原文:http://blog.csdn.net/tian2kong/article/details/20386425