代码之家  ›  专栏  ›  技术社区  ›  gargantuan

JavaScript变量scope/OOP和回调函数所需的帮助

  •  4
  • gargantuan  · 技术社区  · 16 年前

    我认为这个问题超出了典型的变量范围和闭包的范畴,或者我是个白痴。不管怎样。。。

    function WedgePath(canvas){
        this.targetCanvas = canvas;
        this.label;
        this.logLabel = function(){ console.log(this.label) }
    }
    

    jQuery插件如下所示

    (function($) {
      $.fn.myPlugin = function() {
    
      return $(this).each(function() {
    
         // Create Wedge Objects
         for(var i = 1; i <= 30; i++){ 
          var newWedge = new WedgePath(canvas);
          newWedge.label = "my_wedge_"+i;
          globalFunction(i, newWedge]);
         } 
        });
      }
    })(jQuery);
    

    function globalFunction(indicator_id, pWedge){
    
        var targetWedge = pWedge; 
        targetWedge.logLabel();
    
    }
    

    接下来发生的是控制台正确记录每个楔子标签。但是,我需要在globalFunction中增加一点复杂性。所以看起来像这样。。。

    function globalFunction(indicator_id, pWedge){
    
            var targetWedge = pWedge; 
    
            someSql = "SELECT * FROM myTable WHERE id = ?";
            dbInterface.executeSql(someSql, [indicator_id], function(transaction, result){
    
                targetWedge.logLabel();
    
            })
    
        }
    

    这里发生了很多事,我来解释。我正在使用客户端数据库存储(我称之为WebSQL)dbInterface'我创建的一个简单javascript对象的实例,它处理与客户端数据库交互的基础知识[如本问题末尾所示]。executeSql方法最多使用4个参数

    • SQL字符串
    • 可选参数数组
    • 可选的onError处理程序(本例中未使用)

    现在我怀疑问题在于 var newWedge = new WedgePath(canvas) ; 线路。因此,我尝试将每个newWedge推入一个数组,我认为这样可以防止该行在每次迭代时替换或覆盖WedgePath实例。。。

    wedgeArray = [];
    
    // Inside the plugin...
    for(var i = 1; i <= 30; i++){ 
        var newWedge = new WedgePath(canvas);
        newWedge.label = "my_wedge_"+i;
        wedgeArray.push(newWedge);
    } 
    
    for(var i = 0; i < wedgeArray.length; i++){
        wedgeArray[i].logLabel()
    }
    

    我快疯了。我为问题的长度道歉,但我想说得尽可能清楚。

    结束

    ==============================================================

    另外,这里是dbInterface对象的代码,如果它是相关的。

    function DatabaseInterface(db){
    
     var DB = db;
    
     this.sql = function(sql, arr, pSuccessHandler, pErrorHandler){
    
      successHandler = (pSuccessHandler) ? pSuccessHandler : this.defaultSuccessHandler;
      errorHandler = (pErrorHandler) ? pErrorHandler : this.defaultErrorHandler;
    
      DB.transaction(function(tx){
    
       if(!arr || arr.length == 0){
        tx.executeSql(sql, [], successHandler, errorHandler);
       }else{
        tx.executeSql(sql,arr, successHandler, errorHandler)
       }
    
      });      
     }
    
     // ----------------------------------------------------------------
     // A Default Error Handler
     // ----------------------------------------------------------------
    
     this.defaultErrorHandler = function(transaction, error){
      // error.message is a human-readable string.
         // error.code is a numeric error code
         console.log('WebSQL Error: '+error.message+' (Code '+error.code+')');
    
         // Handle errors here
         var we_think_this_error_is_fatal = true;
         if (we_think_this_error_is_fatal) return true;
         return false;
     }
    
    
     // ----------------------------------------------------------------
     // A Default Success Handler
     // This doesn't do anything except log a success message
     // ----------------------------------------------------------------
    
     this.defaultSuccessHandler = function(transaction, results)
      {
          console.log("WebSQL Success. Default success handler. No action taken.");
      }    
    }
    
    2 回复  |  直到 16 年前
        1
  •  3
  •   fredrik    16 年前

    我猜这是因为客户端数据库存储与AJAX调用一样异步运行。这意味着它不会停止调用链以等待调用方法的结果。

    为了解决这个问题,可以在闭包中执行db查询。

    function getDataForIndicatorAndRegion(indicator_id, region_id, pWedge){ 
        return function (targetWedge) { 
            someSql = "SELECT dataRows.status FROM dataRows WHERE indicator_id = ? AND region_id = ?"; 
            dbInterface.sql(someSql, [indicator_id, region_id], function(transaction, result) {
                targetWedge.changeColor(randomHex());
            });
        }(pWedge);
    }
    

    编辑:根据注释更新代码。做了一个改变。回调函数可能不应该是自调用的。如果它自己调用它,函数的结果将作为参数传递。如果不起作用,尝试传递其他参数。

        2
  •  0
  •   Andrew Bullock    16 年前

    我怀疑你的问题是globalFunction内部正在进行的修改闭包:

    function(transaction, result){
    
            targetWedge.logLabel();
    
        })
    

    this