twisted.defer的inlineCallbacks是个修饰符,其真正实现如下:
def inlineCallbacks(f): def unwindGenerator(*args, **kwargs): try: gen = f(*args, **kwargs) except _DefGen_Return: raise TypeError( "inlineCallbacks requires %r to produce a generator; instead" "caught returnValue being used in a non-generator" % (f,)) if not isinstance(gen, types.GeneratorType): raise TypeError( "inlineCallbacks requires %r to produce a generator; " "instead got %r" % (f, gen)) return _inlineCallbacks(None, gen, Deferred()) return mergeFunctionMetadata(f, unwindGenerator)实际上真正调用的是_inlineCallbacks()函数,下面是该函数的详细分析
def _inlineCallbacks(result, g, deferred):
# waiting是用来控制递归的
waiting = [True, # waiting for result?
None] # result
while 1:
try:
# 触发下一个callback,执行结果有4种情况:
# 1)该callback返回一个非Deferred对象,那么回到顶部继续下一轮while,
# 触发下下一个callback,而该非Deferred对象作为下下一个callback的参数;
# 2)执行该callback时触发了一个except,执行异常处理(如果是StopIteration,
# 说明生成器执行完毕,不存在新的元素了);
# 3)该callback返回一个未执行完Deferred对象(表示该callback调用未执行完毕);
# 4)该callback返回一个执行完毕的Deferred对象(表示该callback调用已经执行完毕)
result = g.send(result)
except StopIteration:
# fell off the end, or "return" statement
# deferred.callback(result=None): start processing the callback
# chain starting with the provided result.
# It will be send to the first callback or stored as finally one
# if not any further callback has been specialed yet.
return deferred
deferred.callback(None)
...
if isinstance(result, Deferred):
# a deferred was yielded, get the result.
def gotResult(r):
# 如果waiting[]为True,说明是result是个已经执行完毕的Deferred
# 然后gotResult()是在result.addBoth()中被调用执行的
# 那么通过waiting[1]保存结果,不进行递归,而是继续执行while循环
if waiting[]:
waiting[] = False
waiting[1] = r
else:
_inlineCallbacks(r, g, deferred)
# 当添加result Deferred对象的事件回调时,如果该result是个已经执行完毕的Deferred
#(Deferred对象的callback调用已经执行完毕),那么在addBoth()函数内
# 将直接执行事件回调函数gotResult(),并走gotResult()的if语句,然后又继续回到顶部
# 的while循环触发紧接着的下一个callback调用;如果该result是个未执行完毕的
# Deferred(Deferred对象的callback调用未执行完毕),那么添加该result的
# 完成触发事件gotResult,并执行result.addBoth()下面的if语句,将waiting[]修改
# 为False,然后执行return返回退出while循环。在接下来的时间中,
# 一旦该result对于的callback执行完毕,将触发该result添加的gotResult()回调,
# 并执行_inlineCallbacks(),然后继续执行callback链中的下一个callback调用。
result.addBoth(gotResult)
if waiting[]:
waiting[] = False
return deferred
# 能执行到这里,说明addBoth()中直接执行了gotResult()函数,并将保存在
# waiting[1]中的结果保存到result中,然后回到顶部继续执行while循环
result = waiting[1]
# 为下一轮while循环做准备
waiting[] = True
waiting[1] = None
return deferred