加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-12 18:53:12 所属栏目:百科 来源:网络整理
导读:好吧看起来好像我偶然发现了一个奇怪的计时问题……我为执行sql语句做了一个快速的SQL包装器类.但是,在调用.execute()之后,永远不会触发SQLEvent.RESULT事件,但DB中的新条目将按原样创建.真正奇怪的部分是如果我在调用execute()之后放置一个setTimeout(),事
好吧看起来好像我偶然发现了一个奇怪的计时问题……我为执行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];
    }
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读