无法在for循环中使用JavaScript创建SQLite表

问题描述:

我有一个使用AngularJS,JS,Phonegap/Cordova,Monaca和Onsen UI开发的跨平台应用程序。无法在for循环中使用JavaScript创建SQLite表

我已经在应用程序中实现了一个SQLite数据库来存储各种数据,以确保应用程序可以离线使用。我已经完成了一些简单的测试,并且这些都是按照预期工作的。

我现在尝试创建我需要在应用程序中的所有表(共28)在我的应用程序第一视图小号onDeviceReady()功能。为此我创建了一个对象数组,我将逐个传递给SQLite CREATE语句,如下所示。

设置表中的值

// Form values 
var formValues = [{ 
    tablename: "table_1", 
    id: "id_1", 
    desc: "desc_1", 
    dataType: "TEXT" 
}, { 
    tablename: "table_2", 
    id: "id_2", 
    desc: "desc_2", 
    dataType: "TEXT" 
}, { 
    ... 
    ... 
    ... 
    ... 
}, { 
    tablename: "table_28", 
    id: "id_28", 
    desc: "desc_28", 
    dataType: "TEXT" 
}]; 

创建表

function onDeviceReady() { 
    for (var i = 0; i < formValues.length; i++) { 
     var createFormValues = 'CREATE TABLE IF NOT EXISTS ' + formValues[i].tablename + ' (' + formValues[i].id + ' INTEGER, ' + formValues[i].desc + ' ' + formValues[i].dataType + ')'; 
     alert("SQL: " + createFormValues + 
      "\n\nForm: " + formValues + 
      "\nName: " + formValues[i].tablename + 
      "\nID: " + formValues[i].id + 
      "\nDesc: " + formValues[i].desc + 
      "\nType: " + formValues[i].dataType); 

     db.transaction(function (tx) { tx.executeSql(createFormValues); }); 
    } 
}; 

当我运行上面的代码,警报显示,所有包括SQL语句中的信息OK 。但是,当我查询for()循环后面的每个表时,它表示没有创建表最后一个表除外

然后,我尝试以下哪个DOES创建所有的表,但显然效率低下和管理。

调用函数

createFormTables("table_1", "id_1", "desc_1", "TEXT"); 
createFormTables("table_2", "id_2", "desc_2", "TEXT"); 
createFormTables("...", "...", "...", "..."); 
createFormTables("table_28", "id_28", "desc_28", "TEXT"); 

执行功能

createFormTables: function (tableName, id, description, dataType) { 
    var sql = 'CREATE TABLE IF NOT EXISTS ' + tableName + ' (' + id + ' INTEGER, ' + description + ' ' + dataType + ')'; 
    alert("Create Form Field SQL: " + sql); 
    db.transaction(function (tx) { tx.executeSql(sql); }); 
}, 

我知道SQLite的语句是异步执行的,但我不明白为什么会在第二个创建表例如,而不是第一个?如何使用第一个示例创建表?我可以设置一个$ timeout来执行每个INSERT声明,但这似乎没有必要,并且会导致延迟。

我会使用JavaScript的“对象”的形式给出,以避免冲突调用函数“createFormTables”喜欢的东西时:然后在代码

var QuerySet = function(){ 
//OPTIONAL: I use JQuery Deferred to catch when an async event has finished 
    this.defRes = new $.Deferred(); 
    this.defResProm = this.defRes.promise(); 
}; 

QuerySet.prototype.createFormTables= function(inputData){ 
     //do your stuff and manage when this.defRes is resolved and results it sends back (if a result is needed) 
    this.sqlToExecute = "// YOUR SQL QUERY"; 
    var self=this; 
    $.when(
     (new SqlResult(this.sqlToExecute)).execSqlCustomDeferred(), //read below for SqlResult() explanations 
     self 
    ).done(function(sqlRes,self){ 
     self.defRes.resolve(); 
    }); 

     return this.defResProm; 
}; 

creatFromTables[i] = (new QuerySet()).createFormTables(inputData); 
createFromTables[i].defRes.done(function(res){//do stuff with the result}); 

不需要使用$ .Deferred(),但我认为它可能是有用的,如果你想知道什么时候所有的表已经创建。

这里是用来调用数据库本身的交易SQLRESULT:

var SqlResult = function(sqlToExecute,bracketValues){ 
      //console.log("SqlResult("+sqlToExecute+','+bracketValues+') starts'); 

    this.sqlToExecute = sqlToExecute; 
    this.bracketValues =bracketValues; 
}; 

SqlResult.prototype.execSqlCustomDeferred = function(){ 
     var execSqlCustomDeferredRes = $.Deferred(); 
     var execSqlCustomDeferredResProm = execSqlCustomDeferredRes.promise(); 

     //console.log("SqlResult.execSqlCustomDeferred sqlToExecute is: "+this.sqlToExecute); 
     var sqlToExecuteForTx = this.sqlToExecute; 
     var bracketValuesForTx = this.bracketValues; 

     DbManagement.db.transaction(function(tx){ 

      console.log("SqlResult.execSqlCustomDeferred in TX sqlToExecute is: "+sqlToExecuteForTx); 

      if(bracketValuesForTx!=null){ 
       console.log("SqlResult.execSqlCustomDeferred bracket value is: "+ArrayManagement.arrayToString(bracketValuesForTx)); 
      } 
      tx.executeSql(sqlToExecuteForTx,bracketValuesForTx,success,error); 
      function success(tx,rs){ 
       //console.log('before execSqlCustomDeferredRes resolve ' + execSqlCustomDeferredRes.state()); 
       execSqlCustomDeferredRes.resolve(rs); 
       //console.log('before execSqlCustomDeferredRes resolve after ' + execSqlCustomDeferredRes.state()); 

      } 
      function error(tx,error){ 
       console.log('execSqlCustomDeferred error ' + error.message); 
       execSqlCustomDeferredRes.reject(error); 
      } 

      }); 

     return execSqlCustomDeferredResProm; 
};