刚开始扭曲,只是尝试了一些延迟的内容。我有以下代码组成了100个延迟调用的列表-每个等待一个随机时间并返回一个值。该列表将打印结果,并最终终止反应器。

但是,我很确定我停止反应堆的方式可能是……不是很好。

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


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

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

干杯!

最佳答案

我假设通过添加回调:
      d.addCallback(忽略lambda:reactor.stop())
  收集的结果实际上在所有延迟项上添加了回调?


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

之所以一切都很好,规则且非特殊,是因为gatherResults负责所有必需的逻辑,以便仅在输入的所有Deferred都具有结果之后才给该常规Deferred返回结果。

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

就是说,从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,以便它也不依赖于全局反应堆:

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导入。

您还可以在twisted.internet.task.deferLater中使用getDummyData保存更多的输入内容:

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/

10-12 16:54