【问题标题】:Use deferred to make an infinite call loop使用 deferred 进行无限调用循环
【发布时间】:2010-08-02 19:23:24
【问题描述】:

我们可以使用 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()

【问题讨论】:

    标签: twisted deferred


    【解决方案1】:

    这对 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(我们称其为 b)的回调中返回一个 Deferred(我们称其为 a)会执行称为“链接”的操作。它使b 暂停其回调链,直到a 有结果。在 ab 实际上是同一个 Deferred 实例的情况下,这几乎没有意义。

    其次,当给已经有结果的 Deferred 添加回调时,回调会立即被调用。在您的情况下,您的回调会添加另一个回调。并且该回调添加了另一个回调。因此,您的d.addCallback(loopPrinting) 行中包含一个无限循环。这将防止反应器运行,从而破坏程序的任何其他部分。

    【讨论】:

    • 我试图在我的代码中避免 callLater 或其他基于时间的方法。我正在尝试创建一个函数链,其中一个函数将在前一个函数完成后执行,因此链的运行将独立于时间。有没有办法做到这一点?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-02-04
    • 2018-11-18
    • 1970-01-01
    • 2021-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多