Передача локальной переменной в анонимную функцию-обработчик загрузчика - PullRequest
1 голос
/ 22 октября 2011

Почему это не работает так, как я думаю:

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 объекта, и оператор трассировки выглядит следующим образом:

2
2
2

Вместо:

0
1
2

Если я добавлю i в массив (например, myArr.push(i)), он будет иметь 3 элемента, 0, 1 и 2.

Есть идеи?Спасибо.

Ответы [ 2 ]

3 голосов
/ 22 октября 2011

Это очень плохой подход, который вы выбрали ... Просто не делайте ничего из того, что вы пытаетесь сделать, и все будет хорошо ... Нет смысла использовать здесь анонимную функцию (на самом деле это никогда не бывает)в AS3) нет смысла использовать for-each, потому что вам нужно for(;;).Вы используете динамическую типизацию без какой-либо выгоды (нет никакой выгоды от динамической типизации в AS3 и никогда не было).И да, замыкание будет захватывать контекст, контекст имеет только один i, и его значение равно 2, поэтому первая трасса - это то, что вы должны ожидать.

Что вы должны делать - сохранитьзагрузчики в некоторой структуре данных и извлекать их из этой структуры данных позже (когда вам нужен этот идентификатор).И, пожалуйста, ради нас, пользователей, загрузите все, что вы пытаетесь загрузить последовательно - потому что если вы этого не сделаете, мы получим ошибки ввода-вывода, которые вы не обрабатываете ...

1 голос
/ 23 октября 2011

Сначала позвольте мне сказать вам, почему это не работает так, как вы ожидаете.Происходит то, что for выполняет цикл по вашим элементам и создает все загрузчики, увеличивая i, но Event.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, например, обрабатывать ошибки, и передавать более значимые вещи, чтобы все работало.

...