3

我有一个延迟触发结果。我想将此结果提供给使用它的几个函数。执行此操作的简单方法是将回调添加到 deferred。但是,如果其中一个函数碰巧没有返回相同的结果,那么稍后添加的函数将得到不同的结果,这是我不想要的。为了解决这个问题,我必须执行以下操作:

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

与:

>>> 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。由于我不想修补扭曲的安装以使其正常工作,因此我想知道是否有更清洁的方法来解决此问题。

4

0 回答 0