Лучший способ реализовать асинхронные обратные вызовы / события 1: 1 в ActionScript 3 / Flex / AIR? - PullRequest
1 голос
/ 10 сентября 2008

Я использовал шаблон команды в моих проектах Flex, с маршрутами асинхронного обратного вызова, необходимыми между:

  • кто бы ни создавал конкретный объект команды и объект команды,
  • объект команды и объект «доступ к данным» (т. Е. Тот, кто обрабатывает удаленные вызовы процедур по сети к серверам), которые вызывает объект команды.

Каждый из этих двух маршрутов обратного вызова должен иметь отношение один к одному. Это связано с тем, что у меня может быть несколько экземпляров данного командного класса, выполняющих одно и то же задание одновременно, но с немного другими параметрами, и я не хочу, чтобы их обратные вызовы перепутывались. Таким образом, использование событий, стандартного способа обработки асинхронности в AS3, в значительной степени отсутствует, поскольку они по своей сути основаны на отношениях «один ко многим».

В настоящее время я сделал это, используя ссылки на функции обратного вызова с определенными типами подписей, но мне было интересно знает ли кто-нибудь о лучшем (или альтернативном) способе?

Вот пример, иллюстрирующий мой текущий метод:

  • У меня может быть объект представления, который порождает экземпляр DeleteObjectCommand из-за некоторых действий пользователя, передавая ссылки на две его собственные закрытые функции-члена (одну для успеха, одну для ошибки: скажем, "deleteObjectSuccessHandler()" и "deleteObjectFailureHandler()" в этом примере) в качестве функции обратного вызова ссылается на конструктор класса команды.
  • Тогда объект команды будет повторять этот шаблон с подключением к объекту «доступа к данным».
  • Когда RPC по сети был успешно завершен (или потерпел неудачу), соответствующие функции обратного вызова вызываются сначала объектом «доступа к данным», а затем объектом команды, чтобы, наконец, объект представления, который создал экземпляр операции в первую очередь получает уведомление, если ему позвонили deleteObjectSuccessHandler() или deleteObjectFailureHandler().

Ответы [ 3 ]

3 голосов
/ 10 сентября 2008

Я попробую еще одну идею:

Пусть ваш объект доступа к данным возвращает их собственные AsyncToken (или некоторые другие объекты, которые инкапсулируют ожидающий вызов) вместо AsyncToken, который приходит из вызова RPC. Итак, в DAO это будет выглядеть примерно так (это очень схематичный код):

public function deleteThing( id : String ) : DeferredResponse {
    var deferredResponse : DeferredResponse = new DeferredResponse();

    var asyncToken : AsyncToken = theRemoteObject.deleteThing(id);

    var result : Function = function( o : Object ) : void {
        deferredResponse.notifyResultListeners(o);
    }

    var fault : Function = function( o : Object ) : void {
        deferredResponse.notifyFaultListeners(o);
    }

    asyncToken.addResponder(new ClosureResponder(result, fault));

    return localAsyncToken;
}

Классы DeferredResponse и ClosureResponder, конечно же, не существуют. Вместо того, чтобы придумывать свою собственную, вы могли бы использовать AsyncToken вместо DeferredResponse, но общедоступная версия AsyncToken, похоже, не имеет никакого способа вызывать респонденты, поэтому вам, вероятно, придется все равно ее подклассовать. ClosureResponder - это просто реализация IResponder, которая может вызывать функцию в случае успеха или неудачи.

В любом случае, вышеприведенный код делает свое дело - он вызывает службу RPC, создает объект, инкапсулирующий ожидающий вызов, возвращает этот объект, а затем, когда возвращается RPC, одно из замыканий result или fault вызывается, и, поскольку они все еще имеют ссылки на область, как это было при вызове RPC, они могут вызывать методы для ожидающего вызова / отложенного ответа.

В команде это будет выглядеть примерно так:

public function execute( ) : void {
    var deferredResponse : DeferredResponse = dao.deleteThing("3");

    deferredResponse.addEventListener(ResultEvent.RESULT, onResult);
    deferredResponse.addEventListener(FaultEvent.FAULT,   onFault);
}

или вы можете повторить шаблон, если бы метод execute возвращал свой собственный отложенный ответ, который сработал бы при запуске отложенного ответа, получаемого командой от DAO.

Но. Я не думаю, что это особенно красиво. Возможно, вы могли бы сделать что-то более приятное, менее сложное и менее запутанное, используя одну из множества существующих прикладных сред, чтобы более или менее точно решить эту проблему. Мое предложение будет Mate .

1 голос
/ 10 сентября 2008

Многие из классов Flex RPC, такие как RemoteObject, HTTPService и т. Д., Возвращают AsyncToken с при их вызове. Похоже, это то, что вы ищете. По сути, AsyncToken инкапсулирует ожидающий вызов, что позволяет регистрировать обратные вызовы (в виде экземпляров IResponder) для конкретного вызова.

В случае HTTPService, когда вы вызываете send(), возвращается AsyncToken, и вы можете использовать этот объект для отслеживания конкретного вызова, в отличие от ResultEvent.RESULT, который запускается независимо от того, какой вызов он вызывает есть (и звонки могут легко прийти в другом порядке, чем они были отправлены).

0 голосов
/ 13 мая 2010

AbstractCollection - лучший способ справиться с постоянными объектами в Flex / AIR. GenericDAO дает ответ.

DAO - это объект, который управляет операцией CRUD и другими общими Операции, которые должны быть выполнены над ValueObject (известный как Pojo в Java). GenericDAO - это повторно используемый класс DAO, который можно использовать в общем виде. Цель:

В JAVA IBM GenericDAO, чтобы добавить новый DAO, нужно просто выполнить следующие шаги: Добавьте значениеобъекта (pojo). Добавьте файл отображения hbm.xml для объекта value. Добавьте 10-строчный файл конфигурации Spring для DAO.

Аналогично, в AS3 Project Swiz DAO. Мы хотим достичь таких же результатов.

Модель GenericDAO на стороне клиента: Поскольку мы работали над языком на стороне клиента, мы также должны управлять коллекцией постоянных объектов (для каждого valueObject). Использование: Источник: http://github.com/nsdevaraj/SwizDAO

...