扭曲有序的 DeferredList
twisted ordered DeferredList
是否可以创建一个DeferredList
(或类似的东西),运行所有延迟都按定义的顺序进行?
我需要 运行 一个延迟列表,但理想情况下,延迟列表应该等待前一个,因为它可以改变下一个延迟结果:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
"""
from __future__ import division, absolute_import, \
print_function, unicode_literals
from twisted.internet import defer, reactor
def multiply(n):
if n == 3:
import time
time.sleep(1)
print(n * 10)
return n * 10
def stopIfResultIsAbove20(n):
if n > 20:
print('result is above 20, i would like to stop the following deferreds')
raise Exception('The result is above 20, cancelling the other deferreds')
return n
def onSuccess(result):
print(result)
return result
def onError(failure):
print('failed !')
pass
requests = []
for n in range(0, 6):
d = defer.Deferred()
d.addCallback(multiply)
d.addCallback(stopIfResultIsAbove20)
if n == 3:
from twisted.internet import threads
threads.deferToThread(d.callback, n)
else:
reactor.callLater(0, d.callback, n)
requests.append(d)
dl = defer.DeferredList(requests,
fireOnOneErrback=True)
dl.addCallbacks(onSuccess, onError)
dl.addBoth(lambda _: reactor.stop())
reactor.run()
我想做的事情:
- 创建多个 deferreds
- 每个后续延迟等待前一个
- 如果前一个结果 > 20,则停止所有链
编辑:我可以用 @inlineCallback
装饰器实现这一点,并使代码 同步 ,但我读到应该避免 @inlineCallbacks
,所以我想用传统的延迟代码来实现这个
@inlineCallbacks
没问题。你被告知要避免使用 @inlineCallbacks
的原因是很容易让你的代码像这样意外地顺序化;当您使用 Deferred
s 时,您通常需要并行性,有时如果您的代码看起来很阻塞,您很难注意到您已经放弃了它。但是,如果您了解它的工作原理,那么 @inlineCallbacks
就可以随时使用它;如果您确实想要这样的顺序行为,@inlineCallbacks
是完美的。
是否可以创建一个DeferredList
(或类似的东西),运行所有延迟都按定义的顺序进行?
我需要 运行 一个延迟列表,但理想情况下,延迟列表应该等待前一个,因为它可以改变下一个延迟结果:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
"""
from __future__ import division, absolute_import, \
print_function, unicode_literals
from twisted.internet import defer, reactor
def multiply(n):
if n == 3:
import time
time.sleep(1)
print(n * 10)
return n * 10
def stopIfResultIsAbove20(n):
if n > 20:
print('result is above 20, i would like to stop the following deferreds')
raise Exception('The result is above 20, cancelling the other deferreds')
return n
def onSuccess(result):
print(result)
return result
def onError(failure):
print('failed !')
pass
requests = []
for n in range(0, 6):
d = defer.Deferred()
d.addCallback(multiply)
d.addCallback(stopIfResultIsAbove20)
if n == 3:
from twisted.internet import threads
threads.deferToThread(d.callback, n)
else:
reactor.callLater(0, d.callback, n)
requests.append(d)
dl = defer.DeferredList(requests,
fireOnOneErrback=True)
dl.addCallbacks(onSuccess, onError)
dl.addBoth(lambda _: reactor.stop())
reactor.run()
我想做的事情:
- 创建多个 deferreds
- 每个后续延迟等待前一个
- 如果前一个结果 > 20,则停止所有链
编辑:我可以用 @inlineCallback
装饰器实现这一点,并使代码 同步 ,但我读到应该避免 @inlineCallbacks
,所以我想用传统的延迟代码来实现这个
@inlineCallbacks
没问题。你被告知要避免使用 @inlineCallbacks
的原因是很容易让你的代码像这样意外地顺序化;当您使用 Deferred
s 时,您通常需要并行性,有时如果您的代码看起来很阻塞,您很难注意到您已经放弃了它。但是,如果您了解它的工作原理,那么 @inlineCallbacks
就可以随时使用它;如果您确实想要这样的顺序行为,@inlineCallbacks
是完美的。