views:

335

answers:

2

I am having trouble with implementing this. Basically, I have many large chunks of data that need to load with URLoader. And I want to use lazy loading because eager loading takes up a lot of network resources/time. For example:

class Foo {
    private var _resources:Array;
    public get_resource(id:String){
            if ( _resources[id] == null ){
                 //Load the resource
            }
            return _resources[id];
    }
 }

However, the above code only works with synchronous loading. I don't want the asynchronous being exposed to other parts of the program. How do I do this? Thanks.

+3  A: 

Since an asynchronous function returns immediately (before loading is done), you need to pass a callback function (event handler) to get data from it.

The code may be something like this:

class Foo {
    private var _resources:Array;
    private var _loader:Array; // holds URLLoader objects
    public get_resource(id:String, callback:Function) : void {
        if ( _loader[id] == null ){
            var ld : URLLoader = new URLLoader();

            // instead of returning value, callback function will be
            // called with retrieved data
            ld.addEventListener(Event.COMPLETE, function (ev:Event) : void {
                    _resources[id] = ev.target.data;
                    callback(ev.target.data);
                });

            ld.load (/* URLRequest here */);

            _loader[id] = ld;
        }
        // return nothing for now
    }
}

[edit] removed a wrong comment "// URLLoader object must be held by a class variable to avoid GC". But _loader is still needed for remembering which id is loading.

torus
+1 ... one thing though: "URLLoader object must be held by a class variable to avoid GC" ... that is wrong ... while the URLLoader is loading, the runtime - which actually carries out the loading operation - has a reference to the object (so it can dispatch events back into the VM) ... that's pretty much the reason why also displayObjects on the display list do not get collected, although not referenced by ActionScript ... :)
back2dos
Oh thanks. I didn't know that! On ActionScript1 or 2, the LoadVars object get GCed immediately after the control get out of the scope. So I thought URLLoader is the same.
torus
A: 

i'm afraid you can't ... flash player is single threaded (at least for nearly everything that counts), which is why all I/O operations are asynchronous ...

the solution presented by torus is about the best you can get ...

greetz

back2dos

back2dos