刚开始扭曲,只是尝试了一些延迟的内容。我有以下代码组成了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/