_inlineCallbacks详解

原创 2015年07月10日 21:36:01

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







相关文章推荐

iOS Sonar集成流程详解

  • 2017年11月20日 13:43
  • 683KB
  • 下载

VC++深入详解(修订版) (E)

  • 2017年11月19日 21:06
  • 1.96MB
  • 下载

java 详解异常处理原理

一、Java异常处理机制的优点 在一些传统的编程语言,如C语言中,并没有专门处理异常的机制,程序员通常用方法的特定返回值来表示异常情况,并且程序的正常流程和异常流程都采用同样的流程控制语句。 ...

nginx高性能web服务器详解

  • 2017年11月17日 16:11
  • 27.25MB
  • 下载

fastjson jar 使用详解 实例

  • 2017年11月16日 10:38
  • 357KB
  • 下载

supervisor配置详解(转)

有阵子没写博客了,这段时间一直在研究python django框架和前端相关的东西。楼主学通信的,对web这一块啥也不懂,学了一个礼拜django,接着学了2个礼拜前端,感觉还是做不出来一个好看的页面...

TCP-IP详解卷一:协议.pdf

  • 2017年11月11日 11:00
  • 19.37MB
  • 下载

window.location获取url各项参数详解

Arison [JS]window.location获取url各项参数详解window.location方法后还还可以带href,search等参数,下面我们来看看获取url各项参数的办法。URL即...

TCP-IP详解卷二:实现

  • 2017年11月01日 11:07
  • 36.57MB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:_inlineCallbacks详解
举报原因:
原因补充:

(最多只允许输入30个字)