如何让函数在 SQL 语句的 getResult 可用后等待返回?
我只是想创建一个简单的函数,它将以数组形式返回 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;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
假设我理解你的问题,不要期望 getFavsGamesArray() 实际上从异步事件返回结果(它可能永远不会),而是考虑传递一个函数(作为参数)在 res() 函数中调用,然后该函数将处理数据。
在您的 SQL 帮助程序类中,我们将其称为 SQLHelper.as:
在调用 SQL 帮助程序类的类中:
您也可以选择传递错误处理函数。
Assuming I understood your question, Instead of expecting getFavsGamesArray() to actually return the results from an asynchronous event (which it likely never will), consider passing a function (as an argument) to call within your res() function that would then process the data.
In your SQL helper class, we'll call it SQLHelper.as:
In the class(es) that call your SQL helper class:
You can optionally pass an error handling function as well.
您的问题是您的任务是异步的。
favsArr
是一个临时变量,当getFavsGamesArray
完成时,您可以直接返回它的值。那时,该值将始终为null
,因为侦听器方法仅在 SQL 语句完成后才会调用 - 这将在将来的某个时间完成。您需要某种方法来延迟要对返回值执行的所有操作,直到它实际存在为止。
最好的方法是调度您自己的自定义事件,并将值添加为字段到事件对象,或者将 SQL 类外部的侦听器方法直接添加到
SQLStatement
- 并让它使用event.target.getResult().data
执行操作。这样,当处理发生时,您始终可以确保该值存在,并且使您的 SQL 行为与外部的一切分离。我还强烈建议您不要在函数中声明事件侦听器,如下所示:SQL 语句完成后您无法清理这些侦听器!
正确:在函数内声明函数会使其成为临时函数。也就是说,它仅在您的函数范围内存在,并且当不再需要时它会被垃圾收集 - 就像临时变量一样。但是,如果您将其用作事件侦听器,则“不再需要它”并不适用!这有效的唯一原因是您不使用弱引用 - 如果您这样做,函数将在调用之前被垃圾收集。既然你不这样做,听众就会执行。但如果没有参考,你就无法删除它们!它们和 SQL 语句一样继续存在,即使您将其引用设置为
null
- 并且您已成功创建 内存泄漏。可能不错,但仍然...如果您确实想封装 SQL 行为,那是一件好事。只需考虑将每个 SQL 语句移动到一个专用类,而不是创建一个巨大的 SQLHelper,并将侦听器方法声明为成员函数 - 如果您保留对所有内容的引用,您可以在
destroy
方法中使用它们来正确清理。Your problem is that your task is asynchronous.
favsArr
is a temporary variable, and you return its value directly whengetFavsGamesArray
completes. At that time, the value will always benull
, because the listener methods are called only after the SQL statement is complete - which will be at some time in the future.You need some way to delay everything you are going to do with the return value, until it actually exists.
The best way to do it is to dispatch your own custom event, and add the value as a field to the event object, or to add a listener method outside of your SQL class directly to the
SQLStatement
- and have it do stuff withevent.target.getResult().data
. That way you can always be sure the value exists, when processing occurs, and you keep your SQL behavior decoupled from everything on the outside.I would also strongly encourage you not to declare your event listeners inside functions like this: You can't clean up these listeners after the SQL statements completes!
True: Declaring a function inside a function makes it temporary. That is, it exists only for the scope of your function, and it is garbage collected when it's no longer needed - just like temporary variables. But "it is no longer needed" does not apply if you use it as an event listener! The only reason this works at all is that you don't use weak references - if you did, the functions would be garbage collected before they are even called. Since you don't, the listeners will execute. But then you can't remove them without a reference! They continue to exist, as will the SQL statement, even if you set its references to
null
- and you've successfully created a memory leak. Not a bad one, probably, but still...If you really want to encapsulate your SQL behavior, that is a good thing. Just consider moving each SQL statement to a dedicated class, instead of creating one giant SQLHelper, and having your listener methods declared as member functions - it is much easier to prevent memory leaks and side effects, if you keep references to everything, and you can use these in a
destroy
method to clean up properly.