我有一个延迟,会触发结果。我想把这个结果给几个消耗它的函数。执行此操作的简单方法是向延迟添加回调。但是,如果其中一个函数碰巧没有返回相同的结果,那么稍后添加的函数将获得不同的结果,这是我不想要的。要解决这个问题,我必须做到以下几点:
def branchDeferred(d):
#return a deferred which returns d's results without affecting them
branchD = defer.Deferred()
def success(result):
branchD.callback(result)
return result
def failure(fail):
branchD.errback(fail)
return fail
d.addCallbacks(success, failure)
return branchD
观察区别:
>>> resultD = defer.Deferred()
>>> resultD.addCallback(printCallback)
<Deferred at 0x2a3bcb0>
>>> resultD.addCallback(printCallback)
<Deferred at 0x2a3bcb0>
>>> resultD.callback("lovely")
Result: lovely
Result: None
VS
>>> resultD = defer.Deferred()
>>> branchDeferred(resultD).addCallback(printCallback)
<Deferred at 0x2a2ada0>
>>> branchDeferred(resultD).addCallback(printCallback)
<Deferred at 0x2b658a0>
>>> resultD.callback("lovely")
Result: lovely
Result: lovely
有没有更好的方法来使用内置的扭曲习语来做到这一点,即有什么我还没有理解延迟?或者这是唯一的方法吗?
如果你想知道,这就出现了,因为我使用defer.inlineCallbacks
消耗了延迟产生的结果而不是传播它。
编辑:此代码演示了我在说什么:
>>> class Baz:
def __init__(self):
self.resultD = defer.Deferred()
@defer.inlineCallbacks
def fooMe(self, name):
result = yield self.resultD
print "fooMe(%s) got: %s" % (name, result,)
defer.returnValue(result)
>>> b = Baz()
>>> d1 = b.fooMe("one")
>>> d2 = b.fooMe("two")
>>> b.resultD.callback("SHINIES")
fooMe(one) got: SHINIES
fooMe(two) got: None
_inlineCallbacks()
twisted/internet/defer.py
中的此代码是罪魁祸首:
def gotResult(r):
if waiting[0]:
waiting[0] = False
waiting[1] = r
else:
_inlineCallbacks(r, g, deferred)
result.addBoth(gotResult)
gotResult
最后没有return r
。由于我不想修补我的扭曲安装以使其工作,我想知道是否有更简洁的方法来解决这个问题。