使用deferred进行无限调用循环

时间:2010-08-02 19:23:25

标签: twisted deferred

我们可以使用延迟(http://twistedmatrix.com/documents/current/core/howto/defer.html)来创建一个无限调用循环,其中函数将自己添加到延迟链中吗?我试图这样做,但它不起作用:

d = deferred.Deferred()
first = True

def loopPrinting(dump):
  ch = chr(random.randint(97, 122))
  print ch
  global d, first
  d.addCallback(loopPrinting)
  if first:
    d.callback('a')
    first = False
  return d

loopPrinting('a')

reactor.run()

1 个答案:

答案 0 :(得分:5)

这对Deferreds来说不是一个好用的。相反,请尝试使用reactor.callLater

from twisted.internet import reactor

def loopPrinting():
    print chr(random.randint(97, 122))
    reactor.callLater(1.0, loopPrinting)

loopPrinting()
reactor.run()

twisted.internet.task.LoopingCall

from twisted.internet import task, reactor

def loopPrinting():
    print chr(random.randint(97, 122))

loop = task.LoopingCall(loopPrinting)
loop.start(1.0)
reactor.run()

您的基于延迟的版本有几个问题。首先,它定义了一个Deferred上的回调,它返回相同的Deferred 。从另一个Deferred(让我们称之为a)的回调中返回Deferred(让我们称之为b)会做一些称为“链接”的事情。它会使b暂停其回调链,直到a有结果。在ab实际上是相同的延迟实例的情况下,这几乎没有任何意义。

其次,当向已经有结果的Deferred添加回调时,将立即调用回调。在您的情况下,您的回调会添加另一个回调。而该回调又增加了一个回调。所以你的d.addCallback(loopPrinting)行中包含一个无限循环。这将阻止反应堆运行,破坏程序的任何其他部分。