关闭

_inlineCallbacks详解

标签: twisteddeferinlineCallbacks_inlineCallbackspython
1424人阅读 评论(0) 收藏 举报
分类:

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







0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:109425次
    • 积分:1309
    • 等级:
    • 排名:千里之外
    • 原创:27篇
    • 转载:17篇
    • 译文:0篇
    • 评论:9条
    文章分类
    最新评论