[flexcoders] Re: Best practice for calling asynchronous functions?
--- In flexcoders@yahoogroups.com, Alex Harui wrote: > > I think Amy's point is that, w/o a reference to the anonfun, you can't call removeEventListener on it. If I do: > > someObj.addEventListener("foo", function (e:Event) { ... } ); > > someObj will release the anonfun when it gets garbage collected. However, until that time, all objects in the scope chain won't be collectable. I don't know if that's the case in Java. Yes, that's what I meant. I guess it depends on how you're setting up someObj as to whether someObj would be eligible for garbage collection itself. But the event listeners can't be released independently, except if the thing Ralf suggested works (interesting suggestion, Ralf...I use arguments.callee for other things sometimes myself...never thought of using it that was). Honestly, the reason I don't use anonymous functions is that they don't "feel" like good coding practice to me. -Amy
[flexcoders] Re: Best practice for calling asynchronous functions?
--- In flexcoders@yahoogroups.com, Mark Carter wrote: > Amy-28 wrote: > > > >> As you can imagine, it keeps the implementation > >> much simpler. No need for the ASyncToken. Just add new listeners > > each time a > >> call is made. Everything is garbage collected. Oh, hang on, > > what keeps a > >> reference to the HTTPService? > > > > Good question. What did you do with all the old eventListeners you > > were complaining about in your original post? > > > > My current implementation has something like: > > function save(xml:XML, successFunc:Function, failureFunc:Function):void { > var service:HTTPService = new HTTPService(); > ... > service.addEventListener(ResultEvent.RESULT, > function(evt:ResultEvent):void { > trace("Successfully saved XML"); > successFunc(); > }); > service.send(); // called after the event listeners have been added :) > } > > That's it. The successFunc and failureFunc are only scoped to the calling > code's method and so should be garbage collected when the service is garbage > collected. > > What I don't know is when the service is garbage collected? I'm assuming not > before the result or fault event is fired! My understanding is that anonymous functions _cannot_ get garbage collected unless you use weak references when you add them. Which means there's a really good chance they'll get garbage collected before they get called. HTH; Amy
[flexcoders] Re: Best practice for calling asynchronous functions?
--- In flexcoders@yahoogroups.com, "Tracy Spratt" wrote: > > "...adding responders after the call has been made..." That is not > actually what happens. The call is not made at that line, just set up. > I recall reading a fuller explanation, but didn't follow the internals > well enough to repeat it. Regardless, the flow of the logic doesn't make much sense, especially when someone comes behind you to maintain the code who doesn't know much about remoting...
RE: [flexcoders] Re: Best practice for calling asynchronous functions?
"...adding responders after the call has been made..." That is not actually what happens. The call is not made at that line, just set up. I recall reading a fuller explanation, but didn't follow the internals well enough to repeat it. Tracy From: flexcoders@yahoogroups.com [mailto:[EMAIL PROTECTED] On Behalf Of Amy Sent: Thursday, December 11, 2008 11:47 AM To: flexcoders@yahoogroups.com Subject: [flexcoders] Re: Best practice for calling asynchronous functions? --- In flexcoders@yahoogroups.com <mailto:flexcoders%40yahoogroups.com> , Mark Carter <[EMAIL PROTECTED]> wrote: > > > Thanks for all the responses. > > I hadn't really looked into the ASyncToken until now. However, for me it > seems that using the ASyncToken would be limited to the implementation of > the, for example, save(XML, Function, Function) method. > > The calling code doesn't need to know about it. Right. The calling code doesn't need to do anything different. The change is inside your method. Here's an example: /* Execute method. If calling object passes in result and fault handlers, those are used. Otherwise, the defaults are used. */ public static function execute(categoryID:int=-1, searchString:String=null, resultHandler:Function=null, faultHandler:Function=null):void{ if (_channels.channels.length==0) { throw new Error('No endpoint specified for GetCategories command Remote Object'); } //set up remote object _ro.channelSet=_channels; _ro.destination = 'AMF_Category'; _ro.source = 'AMF_Category'; //set up a token so we can tell the result of this call from other calls var token:AsyncToken=_ro.getServicesCount (categoryID>-1?categoryID: null, searchString); //assign the result and fault handlers from the calling object token.addResponder(new Responder(! (resultHandler==null)?resultHandler:countLoaded, ! (faultHandler==null)? faultHandler: loadFailed)); } /* trace out the return since we don't know where to put it */ private static function countLoaded (e:ResultEvent):void{ trace(e.result.toString() + ' profiles'); } private static function loadFailed(e:FaultEvent):void{ trace(e.fault); } > In my opinion this is neater > than something like: > > var asyncToken:ASyncToken = save(xml); > asyncToken.addResponder(... Suit yourself. You weren't satisfied with what you were using. I offered an alternative. > Also, I don't like adding responders after the call has been made. I know it > works, but still... Me neither. I'm not sure why they built it this way, but unfortunately that's what we have. Just don't dispatch an event in between LOL. > Maybe I should start a new topic for this next question, but... > > ...in my implementation, I create a new HTTPService for each call. Any ideas > how (in)efficient this is? I'm thinking it's pretty bad. > As you can imagine, it keeps the implementation > much simpler. No need for the ASyncToken. Just add new listeners each time a > call is made. Everything is garbage collected. Oh, hang on, what keeps a > reference to the HTTPService? Good question. What did you do with all the old eventListeners you were complaining about in your original post?
[flexcoders] Re: Best practice for calling asynchronous functions?
--- In flexcoders@yahoogroups.com, Mark Carter <[EMAIL PROTECTED]> wrote: > > > Thanks for all the responses. > > I hadn't really looked into the ASyncToken until now. However, for me it > seems that using the ASyncToken would be limited to the implementation of > the, for example, save(XML, Function, Function) method. > > The calling code doesn't need to know about it. Right. The calling code doesn't need to do anything different. The change is inside your method. Here's an example: /* Execute method. If calling object passes in result and fault handlers, those are used. Otherwise, the defaults are used. */ public static function execute(categoryID:int=-1, searchString:String=null, resultHandler:Function=null, faultHandler:Function=null):void{ if (_channels.channels.length==0) { throw new Error('No endpoint specified for GetCategories command Remote Object'); } //set up remote object _ro.channelSet=_channels; _ro.destination = 'AMF_Category'; _ro.source = 'AMF_Category'; //set up a token so we can tell the result of this call from other calls var token:AsyncToken=_ro.getServicesCount (categoryID>-1?categoryID: null, searchString); //assign the result and fault handlers from the calling object token.addResponder(new Responder(! (resultHandler==null)?resultHandler:countLoaded, ! (faultHandler==null)? faultHandler: loadFailed)); } /* trace out the return since we don't know where to put it */ private static function countLoaded (e:ResultEvent):void{ trace(e.result.toString() + ' profiles'); } private static function loadFailed(e:FaultEvent):void{ trace(e.fault); } > In my opinion this is neater > than something like: > > var asyncToken:ASyncToken = save(xml); > asyncToken.addResponder(... Suit yourself. You weren't satisfied with what you were using. I offered an alternative. > Also, I don't like adding responders after the call has been made. I know it > works, but still... Me neither. I'm not sure why they built it this way, but unfortunately that's what we have. Just don't dispatch an event in between LOL. > Maybe I should start a new topic for this next question, but... > > ...in my implementation, I create a new HTTPService for each call. Any ideas > how (in)efficient this is? I'm thinking it's pretty bad. > As you can imagine, it keeps the implementation > much simpler. No need for the ASyncToken. Just add new listeners each time a > call is made. Everything is garbage collected. Oh, hang on, what keeps a > reference to the HTTPService? Good question. What did you do with all the old eventListeners you were complaining about in your original post?
[flexcoders] Re: Best practice for calling asynchronous functions?
--- In flexcoders@yahoogroups.com, "Paul Andrews" <[EMAIL PROTECTED]> wrote: > > - Original Message - > From: "Mark Carter" <[EMAIL PROTECTED]> > To: > Sent: Wednesday, December 10, 2008 8:34 AM > Subject: [flexcoders] Best practice for calling asynchronous functions? > > > > > > In my app, I make a wide variety of XML-RPC calls. Now, to avoid having to > > add/remove listeners all over the place, I've created a class (facade?) > > with > > functions like: > > > > function save(xml:XML, successFunc:Function, failureFunc:Function):void; > > function load(id:String, successFunc:Function, failureFunc:Function):void; > > > > Note, the class' state does not change when any of these functions are > > called. > > > > The class makes the necessary XML-RPC call and listens to the appropriate > > events before calling the relevant success or failure function. The class > > guarantees that either the successFunc or the failureFunc will be called > > at > > some point (but never both). > > > > This makes my calling code very neat: > > > > save(myXML, function(id:String):void { > >Alert.show("Successfully saved XML using id: " + id); > >// now do the next step > > }, function(msg:String):void { > >Alert.show("Failed to save because: " + msg); > >// now rollback > > }); > > > > One obvious drawback of this is that its not so easy to add multiple > > listeners to, say, the save operation. But, in my situation, I never need > > to. > > I would have thought it was very easy to add multiple listeners for the save > operation - just have the single successFunc call multiple functions. The > real problem may be that writing inline functions could make your code > difficullt to follow if they get too complex - I'd probably use inline > functions only for trivial cases. > > Effectively you've replaced event listeners with callback functions. I don't > see the harm in it and I know a lot of people like using callbacks rather > than full blown event handling. > It does look quite neat and enforce cleaning up listeners. Another way to handle it is with a token. The token "rides" the event, so there's no cleanup to be done...Once the event is handled the reference to it goes away, and so does the token and its responders. http://flexdiary.blogspot.com/2008/11/more-thoughts-on-remoting.html