2 Replies Latest reply on Aug 20, 2007 7:34 PM by ntsiii

    Dealing with asynchronous events

    gkidd
      Hi,

      I also posted this in the flex forums because I was unsure which forum is best, I apologize if this is bad form.

      I am currently writing a flex application that speaks to a SOAP webservice. I was able to write actionscript to speak to the webservice operations and everything works fine. Then I got to an operation that actually required multiple webservice operations to be executed serially.

      Initially I took the typically naive (or so I imagine) approach of executing these as if they fired synchronously as I was ignorant, i.e.:

      this._webService.login.addEventListener(ResultEvent.RESULT, handleLoginResult);
      this._webService.getUsers.addEventListener(ResultEvent.RESULT, handleGetUsersResult);


      this._webService.login.send();

      // this operation requires login to have fired so it fails at least some of the time
      this._webService.getUsers.send();


      As you can see this does not work. So then I got to thinking and looking at the core classes and the way they fit together and I came up with the idea of chaining the operations from the handlers since this is where completion occurs, this left me with:

      this._webService.login.addEventListener(ResultEvent.RESULT, handleLoginResult);
      this._webService.getUsers.addEventListener(ResultEvent.RESULT, handleGetUsersResult);

      this._webService.login.send();


      public function handleLoginResult(event:ResultEvent):void
      {
      var someState:Object = event.result;
      this._webService.getUsers.send();
      }

      This appraoch seems to work, but it requires me to author specific handlers for each sequence of operations I need which requires me to add and remove event listeners on a per operation basis based on what sequence I need. This is not reusable and seems very error prone.

      I hit the internet again and I found a blog called kuwamoto.org, which had 3 fascinating articles that sort of dealt with some of the problems I was having, specifically the articles are:

      Dealing with asynchronous events, part 1 - http://kuwamoto.org/2006/05/16/dealing-with-asynchronous-events-part-1/
      Dealing with asynchronous events, part 2 - http://kuwamoto.org/2006/05/16/dealing-with-asynchronous-events-part-2/
      Dealing with asynchronous events, part 3 - http://kuwamoto.org/2006/05/16/dealing-with-asynchronous-events-part-3/

      But even after this, the article does not really address any design patterns for dealing with n-step sequences of operations needed to achieve model state for a given view. So after reading all of this I do have some ideas whereby I could use the AsyncToken returned from the send() methods of each operation to store an object that keeps track of the chain to execute via some generic result handler (chain of responsibility pattern with inversion of control pattern) but then I am starting to think that this appraoch might be overkill.

      So are there any established design patterns for dealing with this problem? Can anyone help me or point me to some article or anything at all. I would greatly appreciate it.
        • 1. Re: Dealing with asynchronous events
          flexPro Level 1
          Check out the CairngormFramework, developed by Adobe Consulting ( http://labs.adobe.com/wiki/index.php/Cairngorm), specifically the SequenceCommand class. Here's the ASDoc text for the SequenceCommand (from http://www.cairngormdocs.org/docs/cairngorm_2_1/):

          The SequenceCommand is provided as a "psuedo-abstract" (since ActionScript has no real concept of abstract classes) base-class that can be extended when you wish to chain commands together for a single user-gesture, or establish some simple form of decision-based workflow.

          By extending SequenceCommand, you can specify the event that should be broadcast to the controller (causing another command execution without a further user-gesture) when the current command has completed execution.

          For a command implementing the Responder interface, you may choose to sequence a subsequent command on successful completion of the command, in the onResult() handler, or on failure of the command in the onFault() method.

          For commands that do not implement the Responder interface, you can simply chain commands by causing the sequenced command to be invoked as the last action in your command's execute() method.
          • 2. Re: Dealing with asynchronous events
            ntsiii Level 3
            I take the easy way, and define a queryId property on AsyncToken. For complex processing I sometimes also include a "callnext" string

            Then in the result handler, a switch statement reads the queryId and callNext strings and performs the next action.

            This actually is easy to amintain, since all the processing logic is in one place.

            Tracy