2009-06-03 5 views
4

Код инициализации нашего приложения Flex выполняет серию асинхронных вызовов для проверки учетных данных пользователя, загрузки внешних данных, подключения к теме JMS и т. Д. В зависимости от контекста приложение , некоторые из этих вызовов не выполняются или не выполняются с различными параметрами.Работа с асинхронными структурами управления (Свободный интерфейс?)

Поскольку все эти вызовы происходят асинхронно, код, управляющий ими, трудно читать, понимать, поддерживать и тестировать. Для каждого вызова нам нужно иметь некоторый механизм обратного вызова, в котором мы решаем, какой вызов выполнить следующий.

Мне было интересно, если бы кто-нибудь экспериментировал с оберткой этих вызовов в исполняемых устройствах и имел Fluent Interface (FI), который будет подключать и управлять ими.

Из верхней части моей головы, код может выглядеть примерно так:

var asyncChain:AsyncChain = execute(LoadSystemSettings) 
.execute(LoadAppContext) 
.if(IsAutologin) 
    .execute(AutoLogin) 
.else() 
    .execute(ShowLoginScreen) 
.etc; 
asyncChain.execute(); 

AsyncChain будет деревом исполнения, строить с ФИ (и мы, конечно, можем также построить один без FI) ,

Это может быть интересной идеей для сред, которые работают в однопоточной модели, как в Flash Player, Silverlight, JavaFX ?, ...

Перед тем, как погрузиться в код, чтобы попробовать вещи, я надеялся, чтобы получить некоторую обратную связь.


Update 19/03/2010: Мы создали экспериментальную Task API в проекте Spring ActionScript, которая обеспечивает контроль над асинхронными процессами. Мы будем рады получить обратную связь. http://www.springactionscript.org/docs/reference/html/the_operation_api.html#tasks

ответ

0

Поскольку ваши функции должны быть асинхронными, вы не можете заставить их блокировать, чтобы дождаться следующего действия, поэтому все, что они делают, - это скопировать некоторые коды в структуру, которая будет выполнена позже.

звучит знакомо? Короче говоря, вы компилируете язык и выполняете виртуальную машину.

ничего плохого в этом нет, но мышление в правильных выражениях позволит вам найти нужную литературу. например, вместо того, чтобы сражаться с вашей внутренней структурой, поэтому часть .else() знает, какая из них .if(), это просто написать полный парсер и отправить ему строку с вашей программой.

также есть много примеров по написанию простых виртуальных машины

1

Определенно вы можете сделать это. Вы можете передавать действия и функции продолжения и угрожать их асинхронному вызову и обратному вызову. Это называется Continuation passing style. Это потребует преобразования обычной логики в последовательность вызовов функций.

Простым способом будет введение некоторой монадической структуры (like in Haskell), которая будет инкапсулировать ваши асинхронные вызовы. Но вам все равно придется создавать несколько функций (обратные вызовы) при преобразовании вашей логики программы в CPS. См.: CPS in Haskell. Но синтаксис уродлив. Хороший синтаксис представлен в Scheme, но это тесно связано с вычислительной моделью Scheme: макросами и библиотечным кодом, доступными для макрообработки.

С некоторой поддержкой языка вы можете упростить синтаксис: пример - это выражения вычислений в F #, точно async one. Под капотом близок относительно концепции Монады.

Еще одна интересная идея программирования с высоким уровнем событий управляется в Reactive Extensions for .NET (Rx). Идея довольно проста: события очень похожи на списки. Разница заключается в том, что вы не создаете их (коллекцию на основе push), а скорее получаете от них следующий элемент (сборка по принципу pull). Инвертируйте интерфейс соответственно: вместо MoveNext и Current в IEnumerator вы получите OnNext, OnDone и OnError в IObservable. Затем, объединяя существующие наблюдаемые, вы можете получить что-то близкое к коду, который вы предложили.

0

Большая часть этого очень интересного обсуждения этого типа программирования. Это также самая слабая часть наших самых распространенных языков, и очень сложно выразить асинхронную логику на синхронном языке. Я считаю, что продолжение здесь является ответом, потому что мы можем легко воспринимать синхронный и программный синхронный, но простой асинхронный поток управления программой. Синхронное программирование очень хорошо понято, и повторное использование очень просто. Асинкс совсем нет. Но, пока мир не догонит ... увы.

То, что вы предлагаете, выглядит интересным, но я делал это сейчас, по крайней мере, дважды и никогда не был доволен этим. Я думаю, что у вас будет трудное время для оценки ваших блоков if во время выполнения. Проблема, с которой я всегда сталкивалась, заключалась в том, чтобы получить данные с одного шага на другой в чистом виде. Как вы собираетесь писать оператор if в отношении значений, которые могут отсутствовать до тех пор, пока не будет выполнен шаг.

Если бы я был вами, я бы рассмотрел шаблон штата. Модель состояния моделирует этот тип поведения в объектах, и переходы могут выполняться асинхронно. Вы могли бы создать интерфейс Fluent для создания таких состояний, как вы уже выше.

Мне было бы очень интересно узнать, как это происходит, когда я делаю это в своем приложении AIR сейчас, и я просто доволен этим.

2

Я сделал что-то подобное, в частности, для инициализации приложений. Однако я написал это с использованием MXML, так как мы разрабатываем большинство наших флеш-приложений с помощью Flex.

Синтаксис выглядит точно так же, как объявить массив (я просто составление тегов, но вы получите идею):

<Initialize> 
    <DisplayPreloader /> 
    <LoadConfiguration id="configurationLoader" source="foo.xml" /> 
    <ParseConfiguration source="{configurationLoader.result}" /> 

    <!-- ... ---> 
</Initialize> 

Использование интерфейсов, таких как IMXMLObject это работает достаточно хорошо, чтобы просто пощечина это в приложение и hey presto, есть ваш код инициализации. Конечно, это не должно быть для инициализации, оно может применяться в любом месте.

Известные профи:

  • Порядок исполнения является интуитивно понятным и легко изменить (просто переместить метку вверх или вниз)
  • Шаги в списке на самом деле не заботится о других шагах
  • Данные может быть передан между этапами с помощью связывания синтаксиса, способствует внедрению зависимости
  • Правильно инкапсулированные шаги одной задачи могут очень легко быть повторно использованы

Заметные минусы:

  • MXML == angle bracket tax
  • Использование привязок для передачи данных может привести к неожиданным результатам, если срабатывает несколько раз
  • следует позаботиться о том, что шаги придерживаться Single Responsibility Principle, в противном случае он может легко стать слишком сложным
1

Если речь идет об использовании Flex и наличии i nsight в потоке асинхронных вызовов я бы использовал археологическую структуру Mate. Как утверждает Api: «Основная часть Mate - это тег EventMap, который позволяет вам определять сопоставления для событий, создаваемых вашим приложением. Это, в основном, список блоков IActionList, где каждый блок соответствует типу события [..] «Теперь в каждой EventMap вы можете иметь несколько асинхронных вызовов сервера, которые логически связаны друг с другом. В целом, это тег mxml, поэтому также очень легко читается.