views:

1533

answers:

4

I have a function that loads a user object from a web service asynchronously.

I wrap this function call in another function and make it synchronous.

For example:

    private function getUser():User{
            var newUser:User;
            var f:UserFactory = new UserFactory();

            f.GetCurrent(function(u:User):void{
                newUser = u;
            });

            return newUser;
        }

UserFactory.GetCurrent looks like this:

public function GetCurrent(callback:Function):void{ }

But my understanding is there is no guarantee that when this function gets called, newUser will actually be the new user??

How do you accomplish this type of return function in Flex?

A: 

You can't convert async call into sync one without something like "sleep()" function and as far as I know it is missing in AS3. And yes, it is not guaranteed that newUser would contain user name before return statement.

vava
+1  A: 

See my answer here:

http://stackoverflow.com/questions/178070/ddd-and-asynchronous-repositories#327288

Flex and Flash Remoting is inherently asynchronous so fighting against that paradigm is going to give you a ton of trouble. Our service delegates return AsyncToken from every method and we've never had a problem with it.

If you want to ensure that the application doesn't render a new view or perform some other logic until the result/fault comes back, you could do the following:

  1. Attach an event listener for a custom event that will invoke your "post result/fault code"
  2. Make the async call
  3. Handle the result/fault
  4. Dispatch the custom event to trigger your listener from #1

Bear in mind this going to lead to a lot of annoying boilterplate code every time you make an async call. I would consider very carefully whether you really need a synchronous execution path.

cliff.meyers
+3  A: 

This way madness lies.

Seriously, you're better off not trying to force an asynchronous call into some kind of synchronous architecture. Learn how the event handling system works in your favour and add a handler for the result event. In fact, here's the advice straight from the flexcoders FAQ :

Q: How do I make synchronous data calls?

A: You CANNOT do synchronous calls. You MUST use the result event. No,
you can't use a loop, or setInterval or even callLater.  This paradigm is
quite aggravating at first. Take a deep breath, surrender to the
inevitable, resistance is futile.

There is a generic way to handle the asynchronous nature of data service
calls called ACT (Asynchronous Call Token). Search for this in
Developing Flex Apps doc for a full description.
inferis
A: 

The AS3 port of the PureMVC framework has mechanisms for implementing synchronous operations in a Model-View-Controller context. It doesn't try to synchronize asynchronous calls, but it lets you add a synchronous application pattern for controlling them.

Here's an example implementation: PureMVC AS3 Sequential Demo.

In this example, five subcommands are run sequentially, together composing a whole command. In your example, you would implement getUser() as a command, which would call commandComplete() in the getURL() (or whatever) callback. This means the next command would be certain that the getUser() operation is finished.

bzlm