How to fix closure problem in ActionScript 3 (AS3)

前端 未结 4 813
Happy的楠姐
Happy的楠姐 2020-12-01 06:31

In the code below I\'m trying to load some images and put them in the stage as soon as they get individually loaded. But it is bugged since only the last image is displayed.

4条回答
  •  不知归路
    2020-12-01 07:19

    Using the more functional style forEach method on the Array class avoids this problem. This has been mentioned already but I'll expand on it here.

    imageList.forEach( function ( item:MovieClip, index:int, list:Array) {
        // add your listener with closure here
    })
    

    Using this method, the function passed into the forEach defines a new scope each iteration. now you can add a closure inside this scope and it will remember each instance as you want.

    On a related note:

    Typing those 3 arguments the whole time is a pain so... You can also make that less / more ugly with an adaptor function:

    // just give me the item please
    imageList.forEach ( itrAdpt( function ( image: ImageData ) {
        // add your listener with closure here
    }))
    
    // give me the item and it's index
    imageList.forEach ( itrAdpt( function ( image: ImageData, index:int ) {
        // add your listener with closure here
    }))
    
    // give me the item, index and total list length
    imageList.forEach ( itrAdpt( function ( image: ImageData, index:int, length:int ) {
        // add your listener with closure here
    }))
    

    where itrAdpt is a (possibly global) function defined something like:

    public function itrAdpt(f: Function): Function
    {
        var argAmount:int = f.length
    
        if (argAmount == 0)
        {
            return function (element:*, index:int, colection:*):* {
                return f(element)
            }
        }
        else if (argAmount == 1)
        {
            return function (element:*, index:int, colection:*):* {
                return f(element)
            }
        }
        else if (argAmount == 2)
        {
            return function (element:*, index:int, colection:*):* {
                return f(element, index)
            }
        }
        else if (argAmount == 3)
        {
            return function (element:*, index:int, colection:*):* {
                return f(element, index, colection.length)
            }
        }
        else
        {
            throw new Error("Don't know what to do with "+argAmount+"arguments. Supplied function should have between 1-3 arguments")
        }
    }
    

提交回复
热议问题