全部博文(921)
分类: Python/Ruby
2012-04-07 10:43:13
from twisted.internet.defer import Deferred, maybeDeferred, DeferredList
from twisted.internet import defer
from twisted.internet import reactor
from twisted.python import failure
import sys, os
def defer_suc(result, suc):
return result + ' defersuc'
def deferrlist_suc(result, suc):
print result
deferrlist = []
for x in range(3):
d = defer.Deferred()
d.addCallback(defer_suc, True).addErrback(defer_suc, False)
deferrlist.append(d)
DeferredList(deferrlist, fireOnOneErrback=1, consumeErrors=1).addCallback(deferrlist_suc, True).addErrback(deferrlist_suc, False)
for x in deferrlist:
x.callback('a')
前面我们对每一个deferr都指定了其回调函数defer_suc,其实这个指定并不是必须的。在为deferr指定回调函数时,它的callback和errback由指定回调执行,否则所有信息都将直接进入到DeferredList的回调函数中。这里需要注意的是当fireOnOneErrback为真时如果deferr未指定errback回调,该deferr的errback都将会导致DeferredList的errback的执行;当fireOnOneErrback为假时,无论deferr是否指定了errback回调,Deferredlist都是由callback回调(不考虑consumeErrors)。下面的例子中 第一次deferrlist_suc的第二个参数为False,第二次为True, 分别表示由errback和callback返回。
for x in range(3):
deferrlist.append(defer.Deferred())
DeferredList(deferrlist, fireOnOneErrback=1, consumeErrors=1).addCallback(deferrlist_suc, True).addErrback(deferrlist_suc, False)
for x in deferrlist:
x.errback('a')
for x in range(3):
deferrlist.append(defer.Deferred())
DeferredList(deferrlist, fireOnOneErrback=1, consumeErrors=1).addCallback(deferrlist_suc, True).addErrback(deferrlist_suc, False)
for x in deferrlist:
x.errback('a')
前面我们提到了deferrlist_suc中的result为一个二元元组列表, 元祖的第一项为True或False,用于说明返回是否为failure对象,第二项为对应的值。 那么在下面的例子中deferrlist_suc会输出什么呢?
def defer_suc(result, suc):
return result
def deferrlist_suc(result, suc):
print result
deferrlist = []
for x in range(3):
d = defer.Deferred()
d.addCallback(defer_suc, True).addErrback(defer_suc, False)
deferrlist.append(d)
DeferredList(deferrlist, consumeErrors=1).addCallback(deferrlist_suc, True).addErrback(deferrlist_suc, False)
deferrlist[0].callback('a')
deferrlist[1].errback('a')
deferrlist[2].callback('a')
result中三个对象一模一样是否让你疑惑,为什么第二个deferr对象明明是errback,元祖第一项还是True呢。 因为deferr对象指定了errback回调函数,在errback发生时,
defer_suc函数就已经将错误吞掉,deferrlist_suc函数看到的都只是正常的返回而已,如果需要将err带入,即让元祖的第一项为False, 那么defer_suc函数返回的对象必须为一个failuer对象
def defer_suc(result, suc):
return result if suc else failure.Failure(result, str)
最后一个问题:如果deferr的回调函数再加入deferrlist之后在指定会如何?根据文档描述,deferr指定的回调是否执行取决于其在回调前或后,如果在会掉前指定的话,该回调函数生效。但我测试时发现无论回调的指定在回调前或后,指定的回调函数都没有执行。 但无论如何请不要将deferr加入到deferrlist后为其指定回调函数,这将导致结果的