Как заставить функцию ждать возврата после того, как getResult из SQL Statement доступен? - PullRequest
0 голосов
/ 17 февраля 2012

Я просто пытаюсь создать простую функцию, которая будет возвращать все данные из моей базы данных SQLITE в виде массива.Но похоже, что когда моя функция возвращает массив, оператор SQL все еще выполняется ... так что он пуст ... У кого-нибудь есть предложение?Или я просто ошибаюсь.

Я знаю, что у меня могли бы быть функции прослушивателя событий вне этой функции, и они могли тогда установить данные.Но я пытаюсь создать класс AS3, который будет содержать все мои функции SQL, и было бы неплохо иметь все для этой конкретной функции только в одной функции, чтобы он мог возвращать мне массив.

 public function getFavsGamesArray():Array
                {
                    getFavsArraySql.addEventListener(SQLEvent.RESULT, res);
                    getFavsArraySql.addEventListener(SQLErrorEvent.ERROR, error);

                    getFavsArraySql.text = "SELECT * FROM favGames";
                    getFavsArraySql.execute();

                    var favsArr:Array = new Array();

                    function res(e:SQLEvent):void
                    {
                        trace("sql good!");
                        favsArr=getFavsArraySql.getResult().data;
                    }

                    function error(e:SQLEvent):void
                    {
                        trace("sql error!");

                    }

                    trace(favsArr);

                    return favsArr;
                }

Ответы [ 2 ]

1 голос
/ 17 февраля 2012

Ваша проблема в том, что ваша задача асинхронная.

favsArr - временная переменная, и вы возвращаете ее значение сразу после завершения getFavsGamesArray.В это время значение всегда будет null, потому что методы прослушивателя вызываются только после завершения оператора SQL, что произойдет в будущем.

Вам нужен какой-то способ отложить все, что вы собираетесь сделать с возвращаемым значением, до его фактического существования.

Лучший способ сделать это - отправить вашесобственного пользовательского события и добавьте значение в качестве поля к объекту события или добавьте метод прослушивателя вне вашего класса SQL непосредственно в SQLStatement - и пусть он работает с event.target.getResult().data.Таким образом, вы всегда можете быть уверены, что значение существует, когда происходит обработка, и вы держите свое поведение SQL отделенным от всего внешнего.

Я бы также настоятельно рекомендовал вам не объявлять прослушиватели событий внутри функций, подобных этой: Вы не можете очистить этих слушателей после завершения операторов SQL!

True: объявление функции внутри функции делает ее временной.То есть он существует только для области действия вашей функции, и он собирает мусор, когда он больше не нужен - как временные переменные.Но «это больше не нужно» не применяется, если вы используете его в качестве прослушивателя событий!Единственная причина, по которой это работает, заключается в том, что вы не используете слабые ссылки - если вы это сделаете, функции будут собирать мусор еще до того, как они будут вызваны.Поскольку вы этого не сделаете, слушатели будут выполнять.Но тогда вы не можете удалить их без ссылки!Они продолжают существовать, как и оператор SQL, даже если вы установите для него ссылки null - и вы успешно создали утечка памяти .Возможно, неплохо, но все же ...

Если вы действительно хотите инкапсулировать свое поведение SQL, это хорошо.Просто рассмотрите возможность перемещения каждого оператора SQL в выделенный класс, вместо создания одного гигантского SQLHelper и объявления ваших методов слушателя как функций-членов - гораздо проще предотвратить утечки памяти и побочные эффекты, если вы сохраняете ссылкико всему, и вы можете использовать их в destroy методе для очистки должным образом.

1 голос
/ 17 февраля 2012

Предполагая, что я понял ваш вопрос, вместо того, чтобы ожидать, что getFavsGamesArray () на самом деле вернет результаты асинхронного события (что, вероятно, никогда не будет), рассмотрите возможность передачи функции (в качестве аргумента) для вызова внутри функции res (), котораязатем обработает данные.

В вашем вспомогательном классе SQL мы назовем его SQLHelper.as:

private var processResultsFun:Function;

public function getFavsGamesArray(callBackFun:Function):void
{ 
    processResultsFun = callBackFun;
    ...

} //Do not return array, instead leave it void

function res(e:SQLEvent):void
{
    trace("sql good!");
    if(processResultsFun != null) 
    {
        processResultsFun(getFavsArraySql.getResult().data);

    }
}

В классе (ах), который вызывает вспомогательный класс SQL:

function processRows(results:Array):void {
    //Make sure this function has an Array argument
    //By the time this is called you should have some results
}
...

SQLHelper.getFavsGamesArray(processRows);

Также можно дополнительно передать функцию обработки ошибок.

...