python - 在 gatherResults 完成后停止扭曲的 react 器

标签 python twisted deferred

twisted 的新手,只是尝试一些延迟的东西。我有以下代码构成了 100 个延迟调用的列表 - 每个等待随机时间并返回一个值。该列表打印结果并最终终止 react 器。

但是,我很确定我停止 react 堆的方式可能...不是很好。

__author__ = 'Charlie'

from twisted.internet import defer, reactor
import random

def getDummyData(x):
    """returns a deferred object that will have a value in some random seconds
    sets up a callLater on the reactor to trgger the callback of d"""
    d = defer.Deferred()
    pause = random.randint(1,10)
    reactor.callLater(pause, d.callback, (x, pause))
    return d


def printData(result):
    """prints whatever is passed to it"""
    print result


def main():
    """makes a collection of deffered calls and then fires them. Stops reactor at end"""
    deferred_calls = [getDummyData(r) for r in range(0,100)]
    d = defer.gatherResults(deferred_calls, consumeErrors = True)
    d.addCallback(printData)

    # this additional callback on d stops the reacor
    # it fires after all the delayed callbacks have printed their values
    # the lambda ignored: ractor.stop() is required as callback takes a function
    # that takes a parameter.
    d.addCallback(lambda ignored: reactor.stop())

    # start the reactor.
    reactor.run()

if __name__ == "__main__":
    main()

我假设通过添加回调:

d.addCallback(lambda ignored: reactor.stop())

收集的结果实际上是在所有延迟的项目上添加回调?

如果是这样,那么可能有更优雅/更正确的方法来做到这一点?

干杯!

最佳答案

I'm assuming that by adding a callback: d.addCallback(lambda ignored: reactor.stop()) to the gathered results actually adds that callback on all the deferred items?

事实并非如此。 gatherResults 返回一个 Deferred。它就像您可能遇到的任何其他 Deferred 一样。它的 addCallback 方法与往常一样做同样的事情:添加一个将在一个回调链中的某一点调用的函数。

之所以一切都像这样很好、规则且不特别,是因为 gatherResults 处理所有必要的逻辑,给常规的 Deferred 它在所有输入 Deferred 都有结果后返回一个结果。

因此,请随意使用 gatherResults,就像使用任何其他 Deferred 返回 API 一样。没什么特别的!

也就是说,从 Twisted 12.3 开始,您可能想使用一个方便的实用程序来完成此类事情 - twisted.internet.task.react。如果您使用它,您的 main 函数将如下所示:

def main(reactor):
    """makes a collection of deffered calls and then fires them. Stops reactor at end"""
    deferred_calls = [getDummyData(r) for r in range(0,100)]
    d = defer.gatherResults(deferred_calls, consumeErrors = True)
    d.addCallback(printData)
    return d

if __name__ == "__main__":
    from twisted.internet import task
    task.react(main, [])

请注意,您可以更改 getDummyData,使其不依赖于全局 react 器:

def getDummyData(reactor, x):
    """returns a deferred object that will have a value in some random seconds
    sets up a callLater on the reactor to trgger the callback of d"""
    d = defer.Deferred()
    pause = random.randint(1,10)
    reactor.callLater(pause, d.callback, (x, pause))
    return d

def main(reactor):
    """makes a collection of deffered calls and then fires them. Stops reactor at end"""
    deferred_calls = [getDummyData(reactor, r) for r in range(0,100)]
    d = defer.gatherResults(deferred_calls, consumeErrors = True)
    d.addCallback(printData)
    return d

现在您的代码根本不需要任何 twisted.internet.reactor 导入。

您还可以在 getDummyData 中使用 twisted.internet.task.deferLater 来节省更多的输入:

def getDummyData(reactor, x):
    """returns a deferred object that will have a value in some random seconds
    sets up a callLater on the reactor to trgger the callback of d"""
    pause = random.randint(1,10)
    return deferLater(reactor, pause, lambda: (x, pause))

关于python - 在 gatherResults 完成后停止扭曲的 react 器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19816613/

相关文章:

python - 需要正则表达式搜索/替换帮助,Python

python - 无法在正则表达式中使用变量

python - twisted + gtk : should I run GUI things in threads, 还是在 react 器线程中?

javascript - 验证失败后 Unresolved promise

python - Twisted Deferred 在没有 errback 的情况下不显示未处理的异常

javascript - 我怎样才能做出瀑布 Q promise ?

python - QTableWidget 无法获取用户输入的数据

python - 加速二维数组上的 NumPy 循环 - 删除相似的行

python : printing in multiple threads

python - 如何 pip install Twisted 而不出现错误?