Actionscript 3 将局部变量传递给加载器匿名处理程序函数

Actionscript 3 将局部变量传递给加载器匿名处理程序函数,actionscript-3,apache-flex,Actionscript 3,Apache Flex,为什么它不能像我想的那样工作: var i:int=-1; for each(obj in myData) { i++; var loader:Loader=new Loader(); loader.contentLoaderInfo.addEventListener(Event.COMPLETE,function(event:Event) { trace(i); }); } myData中有3个对象,trace语句如下所示: 2 2 2

为什么它不能像我想的那样工作:

var i:int=-1;
for each(obj in myData)
{
    i++;
    var loader:Loader=new Loader();
    loader.contentLoaderInfo.addEventListener(Event.COMPLETE,function(event:Event)
    {
        trace(i);
    });
}
myData中有3个对象,trace语句如下所示:

2
2
2
而不是:

0
1
2
如果我将
I
添加到数组中(如
myArr.push(I)
),它将有3个元素,0、1和2

有什么想法吗?
谢谢。

你采取的方法很糟糕。。。只要不要做任何你想做的事情,一切都会好起来的。。。在这里使用匿名函数没有意义(实际上在AS3中从来没有),在每个中使用
也没有意义,因为您需要的是(;;)
。您使用动态键入没有任何好处(在AS3中动态键入没有任何好处,而且从来没有)。是的,闭包将捕获上下文,上下文只有一个
i
,它的值是2,所以第一个跟踪是您应该期望的


您应该做的是——将加载程序存储在某个数据结构中,然后(当您需要该标识符时)从该数据结构中获取它们。为了我们用户的利益,请按顺序加载您试图加载的任何内容-因为如果您不这样做,我们将得到您没有处理的IO错误…

这是一种非常糟糕的方法。。。只要不要做任何你想做的事情,一切都会好起来的。。。在这里使用匿名函数没有意义(实际上在AS3中从来没有),在每个
中使用
也没有意义,因为您需要的是(;;)
。您使用动态键入没有任何好处(在AS3中动态键入没有任何好处,而且从来没有)。是的,闭包将捕获上下文,上下文只有一个
i
,它的值是2,所以第一个跟踪是您应该期望的


您应该做的是——将加载程序存储在某个数据结构中,然后(当您需要该标识符时)从该数据结构中获取它们。为了我们用户的利益,请按顺序加载您试图加载的任何内容,因为如果您不这样做,我们将得到您没有处理的IO错误…

首先,让我告诉您为什么它不能像您期望的那样工作。 现在发生的是,for在元素中循环,并创建所有加载器,递增
i
,但是
事件.COMPLETE
发生在稍后的某个时间,其中
i
已经处于值
2
,因此您会得到该输出

正如wvxvw所建议的,您需要更多的数据结构,如下所示:

class MyLoader {

    private var i: int;
    private var loader: Loader;

    function MyLoader(i:int) {
        this.i = i;

        loader = new Loader();
        loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoaded);
    }

    function onLoaded(event:Event)
    {
        trace(i);
    }
}
您将在循环中使用它:

var i:int = 0;
for each(obj in myData) {
    var loader:MyLoader=new MyLoader(i++);    
}

当然,您需要在MyLoader中添加更多内容,例如处理错误,并传递更多有意义的内容以使一切正常工作。

首先,让我告诉您为什么它不能按预期工作。 现在发生的是,for在元素中循环,并创建所有加载器,递增
i
,但是
事件.COMPLETE
发生在稍后的某个时间,其中
i
已经处于值
2
,因此您会得到该输出

正如wvxvw所建议的,您需要更多的数据结构,如下所示:

class MyLoader {

    private var i: int;
    private var loader: Loader;

    function MyLoader(i:int) {
        this.i = i;

        loader = new Loader();
        loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoaded);
    }

    function onLoaded(event:Event)
    {
        trace(i);
    }
}
您将在循环中使用它:

var i:int = 0;
for each(obj in myData) {
    var loader:MyLoader=new MyLoader(i++);    
}

当然,您需要在MyLoader中添加更多内容,例如处理错误,并传递更多有意义的内容以使一切正常工作。

我认为在AS3中不需要匿名函数是一种过度概括。然而,如果您对理解函数式编程所需的概念有困难,您可能应该避免使用它们。有关如何正确进行函数式编程的更多信息,请仔细阅读并理解使用,匿名函数并不比任何其他语言功能差。使用时不加注意和理解,它们可能会像人们通常不认为危险的其他功能一样危险,例如静力学(但这可能更糟),谢谢。上面的代码是一个简单的例子来说明这个问题。这不是真正的代码。我在监听IOErrors,我不是每次都声明var-loader:loader等等。上面的东西在JS中工作,并且很难理解为什么它在这里不起作用。为什么我不应该对每一个都使用它?我认为这是一种过度概括,在AS3中永远不需要匿名函数。然而,如果您对理解函数式编程所需的概念有困难,您可能应该避免使用它们。有关如何正确进行函数式编程的更多信息,请仔细阅读并理解使用,匿名函数并不比任何其他语言功能差。使用时不加注意和理解,它们可能会像人们通常不认为危险的其他功能一样危险,例如静力学(但这可能更糟),谢谢。上面的代码是一个简单的例子来说明这个问题。这不是真正的代码。我在监听IOErrors,我不是每次都声明var-loader:loader等等。上面的东西在JS中工作,并且很难理解为什么它在这里不工作。为什么我不应该为每一个使用它?啊,我现在明白了。匿名函数在加载所有字节时激发。我认为它像JS一样将is作为一个“变量”保存,并像声明它时一样保存在其中。谢谢。您正在考虑JavaScript中的闭包。。ActionScript(作为ECMAScript的变体)也可以这样做,但您必须将所有内容包装在另一个函数中,并将
i
存储在局部变量中,如下所示:。啊,我现在明白了。匿名函数在加载所有字节时激发。我认为它像JS一样将is作为一个“变量”保存,并像声明它时一样保存在其中。谢谢。您正在考虑JavaScript中的闭包。。ActionScript(ECMAScript变体)也可以这样做,但您必须将所有内容包装到另一个函数中,并将
i
存储在局部变量中,如下所示:。