微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

AIR Sqlite:SQLEvent.RESULT未触发,但语句IS正确执行

好吧看起来好像我偶然发现了一个奇怪的计时问题……我为执行sql语句做了一个快速sql包装器类.但是,在调用.execute()之后,永远不会触发sqlEvent.RESULT事件,但DB中的新条目将按原样创建.真正奇怪的部分是如果我在调用execute()之后放置一个setTimeout(),事件会按预期触发..我希望我在这里找不到一些非常明显的东西……这是一个示例air app的链接
http://www.massivepoint.com/airsqltest/AIRSQL.zip

以下是包装类的代码

如果你向下看sqlRequest类中的第51行,你会看到注释掉的setTimeout()方法.为了让一切顺利,只要取消注释那条线……但对我来说这没有任何意义……

有人有什么想法?我完全被这里难过……

package com.jac.sqlite 
{//Package
 import flash.data.sqlConnection;
 import flash.data.sqlStatement;
 import flash.events.Eventdispatcher;
 import flash.events.sqlErrorEvent;
 import flash.events.sqlEvent;
 import flash.utils.setTimeout;

 public class sqlRequest extends Eventdispatcher
 {//sqlRequest Class

  private var _callback:Function;
  private var _dbConn:sqlConnection;
  private var _query:String;
  private var _params:Object;

  private var _statement:sqlStatement;


  public function sqlRequest(callback:Function,connection:sqlConnection,query:String,parameters:Object=null):void 
  {//sqlRequest
   trace("Creating new sql Request");
   _callback = callback;
   _dbConn = connection;
   _query = query;
   _params = parameters;


   _statement = new sqlStatement();
   _statement.sqlConnection = _dbConn;
   _statement.text = _query;

   if (_params != null)
   {//assign
    for (var param:String in _params)
    {//params
     trace("Setting Param: " + param + " to: " + _params[param]);
     _statement.parameters[param] = _params[param];
    }//params
   }//assign

   //setup events
   _statement.addEventListener(sqlEvent.RESULT,handleResult,false,true);
   _statement.addEventListener(sqlErrorEvent.ERROR,handleError,true);
  }//sqlRequest

  public function startLoad():void
  {//execute
   _statement.execute();
   //setTimeout(handleTimeOut,10000);
  }//execute

  //TEMP
  private function handleTimeOut():void
  {//handleTimeOut
   trace("Executing: " + _statement.executing + " / " + executing);
  }//handleTimeOut

  private function handleResult(e:sqlEvent):void 
  {//handleResult
   trace("Good sql Request");
   _callback(e);
   dispatchEvent(e);
  }//handleResult

  private function handleError(e:sqlErrorEvent):void 
  {//handleError
   trace("sql Error: " + e.errorID + ": " + e.error);
   //dispatchEvent(e);
  }//handleError

  public function get executing():Boolean
  {//get executing
   return _statement.executing;
  }//get executing

  public function get query():String { return _query; }
  public function get statement():sqlStatement { return _statement; }

 }//sqlRequest Class

}//Package

解决方法

我想你在这里缺少的是垃圾收集.

没有测试过您的代码,但这肯定是问题的根源.

var sqlReq:sqlRequest = new sqlRequest(handleResult,_dbConn,sql);
sqlReq.startLoad();

引用sqlReq是函数的本地函数,并在函数返回时变为不可缓存.这使它可收藏.我想在AIR运行时必须有一些代码,当涉及到sql连接时,它会更加积极地收集垃圾.因为通常情况下,你不会将ref存储到你的对象中(至少在基于web的环境中,根据我的经验;这是这类代码中的一个错误;然而你只需要在糟糕的一天中体验它).

setTimeout掩盖了这个问题(或者几乎解决了它,尽管是以一种无意的方式),因为setTimeout函数在内部使用了Timer.不收集运行计时器.因此,计时器处于活动状态并且具有对sqlRequest实例的引用,这使得它可以进行访问,因此不适合收集.如果您的数据库调用花费的时间超过了超时,那么您将恢复相同的状态.

解决此问题,请将ref存储到对象并在完成后正确处理.

编辑

一个选项,如果你不想改变调用代码的方式,则在调用期间将一个ref存储在类范围(即静态)字典中(该字典不应使用弱引用键原因很明显).

您正在为方法添加隐藏的副作用,这通常不是良好设计的标志,但只要在完成对DB的调用(无论是否成功)时将其删除,您就是安全的,所以我认为问题更多的是风格而不是其他任何东西.

我的意思是这样的:

private static var _dict:Dictionary = new Dictionary();

public function startLoad():void
{//execute
    _statement.execute();
    //  add a self reference to dict so the instance won't be collected
    //  do this in the last line,so if we have an exception in execute,this
    //  code will not run (or add a try/catch if you want,but this is simpler
    //  and cleaner,IMO
    addToDict();
}//execute

private function handleResult(e:sqlEvent):void 
{//handleResult
    //  remove the self reference before running any other code
    //  (again,this is in case the code that follows throws)
    removeFromDict();
    trace("Good sql Request");
    _callback(e);
    dispatchEvent(e);
}//handleResult

private function handleError(e:sqlErrorEvent):void 
{//handleError
    //  same comment as handleResult
    removeFromDict();
    trace("sql Error: " + e.errorID + ": " + e.error);
    //dispatchEvent(e);
}//handleError

private function addToDict():void {
    _dict[this] = true;
}

private function removeFromDict():void {
    if(_dict[this]) {
        delete _dict[this];
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐