ActionScript 3.0 using closures for event handlers

前端 未结 9 1921
挽巷
挽巷 2020-12-28 18:35

I tried doing this:

root.addEventListener(\"click\", 
   function () 
   { 
      navigateToURL(ClickURLRequest,\"_self\"); 
   });

And it

9条回答
  •  醉梦人生
    2020-12-28 19:28

    As has already been suggested, you may remove the closure from the chain of listeners from within the closure itself. This is done through the use of arguments.callee:

    myDispatcher.addEventListener("click", function(event:Event):void
    {
        IEventDispatcher(event.target).removeEventListener(event.type, arguments.callee);
    
        // Whatever else needs doing goes here
    });
    

    This will effectively turn the closure into a one-time listener of the event, simply detaching itself once the event has fired. While syntactically verbose, it's an incredibly useful technique for those many events that really only fire once (or that you only care about once) like "creationComplete" in Flex, for instance. I use this all the time when downloading data, since I think having the callback code inline makes it easier to understand. It is like hiding away the asynchronous-ness:

    myLoader.addEventListener("complete", function(event:Event):void
    {
        /* Even though the load is asynchronous, having the callback code inline
         * like this instead of scattered around makes it easier to understand,
         * in my opinion. */
    });
    

    However, if you want to listen to the event multiple times, this will not be very effective for obvious reasons. In that case, you need to store a reference to the closure somewhere. Methods are objects like anything else in ActionScript and can be passed around. Thus, we can alter our code to look like this:

    var closure:Function;
    
    myDispatcher.addEventListener("click", function(event:Event):void
    {
        closure = arguments.callee;
    
        // Whatever else needs doing goes here
    });
    

    When you need to remove the event listener, use the 'closure' reference, like so:

    myDispatcher.removeEventListener("click", closure);
    

    Obviously, this is an abstract example but using closures like this can be pretty useful. They do have drawbacks though, such as being less efficient than named methods. Another drawback is the fact that you actually have to store away a reference to the closure if you ever need it. Care must then be taken to preserve the integrity of that reference, just like with any other variable.

    Thus, while the different syntax may have its uses, it's not always the best solution. It's an apples and oranges kind of thing.

提交回复
热议问题