¿La mejor manera de implementar eventos/devoluciones de llamadas asincrónicas 1:1 en ActionScript 3/Flex/AIR?

StackOverflow https://stackoverflow.com/questions/53025

Pregunta

He estado utilizando el patrón de comando en mis proyectos Flex, con rutas de devolución de llamada asincrónicas requeridas entre:

  • quien haya creado una instancia de un objeto de comando determinado y el objeto de comando,
  • el objeto de comando y el objeto de "acceso a datos" (es decir,alguien que maneja las llamadas al procedimiento remoto a través de la red a los servidores) que llama el objeto de comando.

Cada una de estas dos rutas de devolución de llamada debe poder tener una relación uno a uno.Esto se debe al hecho de que puedo tener varias instancias de una determinada clase de comando ejecutando exactamente el mismo trabajo al mismo tiempo pero con parámetros ligeramente diferentes, y no quiero que sus devoluciones de llamada se mezclen.Por lo tanto, el uso de eventos, la forma predeterminada de manejar la asincronicidad en AS3, está prácticamente descartado ya que se basan inherentemente en relaciones de uno a muchos.

Actualmente he hecho esto usando referencias de la función de devolución de llamada con tipos específicos de firmas, pero me preguntaba ¿Si alguien conociera una forma mejor (o alternativa)?

Aquí hay un ejemplo para ilustrar mi método actual:

  • Podría tener un objeto de vista que genere un DeleteObjectCommand instancia debido a alguna acción del usuario, pasando referencias a dos de sus propias funciones miembro privadas (una para el éxito, otra para el fracaso):digamos "deleteObjectSuccessHandler()" y "deleteObjectFailureHandler()" en este ejemplo) como referencias de función de devolución de llamada al constructor de la clase de comando.
  • Luego, el objeto de comando repetiría este patrón con su conexión al objeto de "acceso a datos".
  • Cuando el RPC a través de la red se ha completado con éxito (o ha fallado), se llaman las funciones de devolución de llamada apropiadas, primero por el objeto de "acceso a datos" y luego por el objeto de comando, de modo que finalmente el objeto de vista que instancia la operación en la primera lugar es notificado al tener su deleteObjectSuccessHandler() o deleteObjectFailureHandler() llamado.
¿Fue útil?

Solución

Probaré una idea más:

Haga que su objeto de acceso a datos devuelva sus propios AsyncTokens (u otros objetos que encapsulan una llamada pendiente), en lugar del AsyncToken que proviene de la llamada RPC.Entonces, en DAO se vería así (este es un código muy incompleto):

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;
}

El DeferredResponse y ClosureResponder Las clases no existen, por supuesto.En lugar de inventar el tuyo propio, podrías usar AsyncToken en lugar de DeferredResponse, pero la versión pública de AsyncToken no parece tener ninguna forma de activar los respondedores, por lo que probablemente tendrías que subclasificarlo de todos modos. ClosureResponder es solo una implementación de IResponder que puede llamar a una función en caso de éxito o fracaso.

De todos modos, la forma en que el código anterior funciona es que llama a un servicio RPC, crea un objeto que encapsula la llamada pendiente, devuelve ese objeto y luego, cuando regresa el RPC, uno de los cierres result o fault se llama, y ​​dado que todavía tienen referencias al alcance como estaba cuando se realizó la llamada RPC, pueden activar los métodos en la llamada pendiente/respuesta diferida.

En el comando se vería así:

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

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

o bien, podrías repetir el patrón, teniendo el execute El método devuelve una respuesta diferida propia que se activaría cuando se active la respuesta diferida que el comando recibe del DAO.

Pero.No creo que esto sea particularmente bonito.Probablemente podrías hacer algo mejor, menos complejo y menos complicado utilizando uno de los muchos marcos de aplicaciones que existen para resolver más o menos exactamente este tipo de problema.Mi sugerencia sería Compañero.

Otros consejos

Muchas de las clases Flex RPC, como RemoteObject, HTTPService, etc.devolver AsyncTokens cuando los llamas.Parece que esto es lo que buscas.Básicamente el AsyncToken encapsula la llamada pendiente, lo que permite registrar devoluciones de llamada (en forma de IResponder instancias) a una llamada específica.

En el caso de HTTPService, cuando usted llama send() un AsyncToken se devuelve, y puede usar este objeto para rastrear la llamada específica, a diferencia del ResultEvent.RESULT, que se activa independientemente de qué llamada sea (y las llamadas pueden llegar fácilmente en un orden diferente al de su envío).

AbstractCollection es la mejor manera de lidiar con objetos persistentes en Flex/AIR.GenericDAO proporciona la respuesta.

DAO es el objeto que logra realizar la operación CRUD y otras operaciones comunes que se realizarán sobre un ValueObject (conocido como POJO en Java).GenericDAO es una clase DAO reutilizable que se puede utilizar de forma genérica.Meta:

En Java IBM GenericDao, para agregar un nuevo DAO, los pasos a hacer es simplemente, agregar un ValueObject (POJO).Agregue un archivo de mapeo hbm.xml para el objeto de valor.Agregue el archivo de configuración Spring de 10 líneas para DAO.

De manera similar, en AS3 Proyecto Swiz DAO.Queremos alcanzar el mismo nivel de logro.

Modelo GenericDAO del lado del cliente:Como estábamos trabajando en un lenguaje del lado del cliente, también deberíamos administrar una colección de objetos persistentes (para cada objeto de valor).Uso:Fuente:http://github.com/nsdevaraj/SwizDAO

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top