Я буду использовать Python в качестве примера, как это то, что я использую для создания огромных распределенных приложений прямо сейчас.
Twisted python допускает очень императивный стиль, используя либо inlinecallbacks, либо (слегка уродливые) отложенные стили генератора. Эти методы позволяют вам писать процедуры, которые используют код обратного вызова, управляемый событиями, который намного легче читать и понимать. Реализация превращает вашу функцию в ленивую последовательность, которая дает последовательность отсрочек.
В частности, вам не нужно создавать глубоко вложенный набор функций обратного вызова/lambdas/closures и вместо этого вместо этого управлять контролем функции в цикле событий в произвольных точках. Вы можете мысленно перемаркировать это как сопрограммы или совместную многозадачность, если хотите. Он выполняет свою работу. Пример может быть (с использованием нелицеприятного стиля deferredGenerator), как это:
@defer.deferredGenerator
def foo(arg):
bar = nonBlockingFunction(foo)
baz = waitForDeferred(aFunctionThatReturnsADeferredToo(bar))
yield baz #Returns control to the event loop
output = baz.getResult() #This gets the output of aFunctionThat...Too above
yield output #This is how we return a result instead of using return
@defer.deferredGenerator
def aFunctionThatReturnsADeferredToo(put_bar_here):
"""Stuff happens here...."""
...etc...
Существует еще один пост здесь, что показывает метод inlineCallbacks, который чист, но требует Python 2.5 или более поздней версию (что означает не под Centos/RHEL 5 серии, которые я, к сожалению, застрял для своего приложения). Если вы можете использовать его, DO SO.
Как вы можете видеть, это похоже на старый учебный материал для питона, который вы знаете и любите, но его легко поддерживать без тонны вложенных функций и лямбда. Я все еще хочу, чтобы у python были блоки.
Что касается отладки, вы можете включить отладку открученного реактора, используя вызов defer.setDebugging (True) где-то в вашем коде инициализации. Это приложит исходную трассировку, которая вызвала бы исключение в вашем коде, чтобы вы могли тривиально увидеть, где произошла ошибка ACTUALLY. Просто не забудьте отредактировать оператор setDebugging перед тем, как начать производство, потому что это приводит к ОГРОМНОЙ сумме дополнительной интроспекции (смотрите ее в strace, если хотите, чтобы вы были в ужасе).
заботиться о разработке? – keyle