扭曲有序的 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()

我想做的事情:

编辑:我可以用 @inlineCallback 装饰器实现这一点,并使代码 同步 ,但我读到应该避免 @inlineCallbacks,所以我想用传统的延迟代码来实现这个

@inlineCallbacks没问题。你被告知要避免使用 @inlineCallbacks 的原因是很容易让你的代码像这样意外地顺序化;当您使用 Deferreds 时,您通常需要并行性,有时如果您的代码看起来很阻塞,您很难注意到您已经放弃了它。但是,如果您了解它的工作原理,那么 @inlineCallbacks 就可以随时使用它;如果您确实想要这样的顺序行为,@inlineCallbacks 是完美的。