1

当我从我的测试方法调用 DoSomething() 方法时,我希望它阻止 Connect() 中的产量,但它没有,它返回一个未调用但已延迟。

Class Foo:
    @defer.inlineCallbacks
    def Connect(self):
        amqpConfig = AmqpConfig(self.config.getConfigFile())
        self.amqp = AmqpFactory(amqpConfig)

        try:
            # First Deferred
            d = self.amqp.connect()
            # Second Deferred
            d.addCallback(lambda ign: self.amqp.getChannelReadyDeferred()) 

            # Block until connecting and getting an AMQP channel
            yield d
        except Exception, e:
            self.log.error('Cannot connect to AMQP broker: %s', e)

    def DoSomething(self):
        c = self.Connect()
        # None of the deferreds were fired, c.called is False

我怎样才能让它阻塞直到第二个(也是最后一个)延迟被调用?

4

2 回答 2

2

Your call to self.Connect() in DoSomething() is supposed to return a not-yet-fired Deferred; that's how inlineCallbacks works. The code at the beginning of Connect() should have been called, but once it hit the first yield it just returned its Deferred to your caller. Later on, when the AMQP channel is acquired, that Deferred will fire.

If you want the DoSomething() call to... do something :) after the c Deferred fires, and you don't want to make DoSomething() into another inlineCallbacks method, then just use the Deferred in the normal way: addCallback() and friends. Example:

def DoSomething(self):
    c = self.Connect()
    c.addCallback(self.handle_getting_amqp_channel)
    c.addErrback(self.this_gets_called_if_something_went_wrong)
    return c

For more information on how Twisted Deferreds work, see http://twistedmatrix.com/documents/current/core/howto/defer.html . Hope this helps.

于 2012-05-21T18:43:57.883 回答
1

代码似乎不太清楚(尤其是第 4 行缩进)。但是,如果我做对了self.Connect()调用返回一个延迟本身,所以你必须使用:

c =产生self.Connect()

为了防止它在后台运行并将deferredResult返回到c变量。

于 2012-05-21T07:13:04.497 回答