问题描述
刚开始扭曲,只是尝试了一些延迟的东西。我有以下代码组成了100个延迟调用的列表-每个等待一个随机时间并返回一个值。该列表将打印结果,并最终终止反应堆。
new to twisted and just trying some deferred stuff out. I have the following code that makes up a list of 100 deferred calls - each waiting a random time and returning a value. That list the prints the results and finally terminates the reactor.
但是,我很确定我停止反应堆的方式可能是……不太好。
However, I'm pretty sure the way I'm stopping the reactor is probably... not great.
__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())
到收集的结果中实际上在所有延迟项目上添加了回调?
to the gathered results actually adds that callback on all the deferred items?
如果这样的话,可能有一种更优雅/更正确的方法呢?
if so then there is probably a more elegant / correct way to do it?
干杯! / p>
Cheers!
推荐答案
这并非如此。 gatherResults
返回一个 new Deferred
。就像您遇到的任何其他 Deferred
一样。它的 addCallback
方法与往常一样:添加一个将在一个回调链中的某一时刻被调用的函数。
This isn't the case. gatherResults
returns a new Deferred
. It's just like any other Deferred
you might come across. Its addCallback
method does the same thing as usual: adds one function that will be called at one point in one callback chain.
之所以一切正常,正常且非常规,是因为 gatherResults
照顾了 only 赋予常规 Deferred
,它在所有输入 Deferred
都具有结果之后返回结果。
The reason everything is nice and regular and unspecial like this is that gatherResults
takes care of all the logic necessary to only give that regular Deferred
that it returns a result after all of the input Deferred
s have a result.
因此,随时使用 gatherResults
,就像您使用任何其他 Deferred
-返回API。
So, feel free to use gatherResults
just like you're use any other Deferred
-returning API. It's not special!
也就是说,从Twisted 12.3开始,您可能想要使用一种方便的实用程序- twisted。 internet.task.react
。如果您使用它,这就是您的 main
函数的样子:
That said, starting with Twisted 12.3 there's a handy utility that you might want to use for this sort of thing - twisted.internet.task.react
. Here's what your main
function would look like if you used it:
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
,以便它也不依赖于全局反应堆:
And notice that you could change getDummyData
so that it doesn't depend on the global reactor either:
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
导入。
And now your code does't need any twisted.internet.reactor
imports at all.
您还可以使用 twisted.internet.task。
可以节省更多键入: getDummyData
中的deferLater
You could also use twisted.internet.task.deferLater
in getDummyData
to save a bit more typing:
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))
这篇关于在gatherResults完成后停止扭曲的反应堆的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!