_inlineCallbacks详解

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







  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值