gpt4 book ai didi

javascript - JavaScript 变量作用域/OOP 和回调函数需要帮助

转载 作者:塔克拉玛干 更新时间:2023-11-02 21:07:37 25 4
gpt4 key购买 nike

我认为这个问题超出了典型的变量范围和闭包范围,或者我是个白痴。无论如何……

我正在 jQuery 插件中动态创建一堆对象。该对象看起来像这样

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);

所以...插件创建了一堆 wedgeObjects,然后为每个调用“globalFunction”,传入最新的 WedgePath 实例。全局函数看起来像这样。

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 字符串
  • 一个可选的参数数组
  • 一个可选的 onSuccess 处理程序
  • 可选的 onError 处理程序(本例中未使用)

我需要做的是:当 WebSQL 查询完成时,它会获取一些数据并处理特定楔形的某些属性。但是,当我在 onSuccess 处理程序中的 WedgePath 实例上调用“logLabel”时,我得到了在插件代码中创建的最后一个 WedgePath 实例的标签。

现在我怀疑问题出在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()
}

但是,我再次创建了 WedgePath 的最后一个实例。

这让我抓狂。对于问题的长度,我深表歉意,但我想尽可能清楚。

结束

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

另外,这里是 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.");
}
}

最佳答案

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

因此,javascript 引擎在运行 globalFunction 之前完成了 for 循环。

要解决此问题,您可以在闭包内执行数据库查询。

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);
}

这样您就可以为每次执行保留 pWedge。由于第二种方法是自行调用它并将 pWedge 现在作为参数发送。

编辑:更新评论中的代码。并对其进行了更改。回调函数可能不应该被自己调用。如果它自己调用它,则函数的结果作为参数传递。另外,如果它不起作用,请尝试传递其他参数。

关于javascript - JavaScript 变量作用域/OOP 和回调函数需要帮助,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2856076/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com