使用 deferred 进行无限调用循环

发布于 2024-09-12 08:17:18 字数 512 浏览 1 评论 0原文

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

Can we use deferred (http://twistedmatrix.com/documents/current/core/howto/defer.html) to make an infinite call loop in which a function adds itself to a deferred chain? I tried to do this, but it doesn't work:

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()

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

扛刀软妹 2024-09-19 08:17:18

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

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

This isn't a good use for Deferreds. Instead, try using reactor.callLater:

from twisted.internet import reactor

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

loopPrinting()
reactor.run()

Or 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()

Your Deferred-based version has a couple problems. First, it defines a callback on a Deferred that returns the same Deferred. Returning a Deferred (let's call it a) from a callback on another Deferred (let's call it b) does something called "chaining". It makes b pause its callback chain until a has a result. In the case where a and b are actually the same Deferred instance, this makes little or no sense.

Second, when adding a callback to a Deferred that already has a result, the callback will be called immediately. In your case, your callback adds another callback. And that callback adds another callback. So you have an infinite loop all contained inside your d.addCallback(loopPrinting) line. This will prevent the reactor from ever running, breaking any other part of your program.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文