JavaScript文字对象执行顺序错误

时间:2012-12-23 18:16:57

标签: sqlite javascript-objects

我现在正在学习JavaScript面向对象,并尝试从HTML5 SQLite的DB类构建文字对象。

问题是,在某一点上,某些方法没有以正确的顺序执行,我需要的是什么。这是班级:

var DB = function(dbName, dbVersion, dbDescription, dbSize){
var dbConnection    = null;
var is_connected    = false;

var dbName          = dbName;
var dbVersion       = dbVersion;
var dbDescription   = dbDescription;
var dbSize          = dbSize;

var existingTables  = new Array();

var connect = function(){
    Debug.log('auto connect ...');
    try{
        if (!window.openDatabase) {
            Debug.log('SQLite not supported');
        }
        else{
            dbConnection = window.openDatabase(dbName, dbVersion, dbDescription, dbSize);
            is_connected = true;
        }
    }
    catch(e){
        if (e == INVALID_STATE_ERR) {
            // Version number mismatch.
            Debug.log("Invalid database version.");
        }
        else{
            Debug.log(e.message);
        }
        return;
    }
}();

var checkTables = function(){
    dbConnection.transaction(function (tx) {
        tx.executeSql('SELECT name FROM sqlite_master WHERE type="table"', [], function(tx, rs) {
            for( var i = 0; i < rs.rows.length; i++ ) {
                Debug.log(rs.rows.item(i).name);
                existingTables.push( rs.rows.item(i).name );
            }
          }, function (tx, err){
              Debug.log(err.message);
              return true;
        });
    });
}();

// public methods
return {
    isConnected : function(){
        return is_connected;
    },
    close : function(){
        // close the DB connection
    },
    tableExists : function(table){
        Debug.log('table: '+table);

        // existingTables == 0 - WHY?
        alert(existingTables.length);

    },
    tableCreate : function(table){
        switch(table){
            case 'foo':
                var cr_sql = 'CREATE TABLE foo (id unique, text)';
            break;
        }

        // create the missing table
        dbConnection.transaction(function (tx) {
            tx.executeSql(cr_sql, [], function(tx, rs) {
                    return true;
                }, function (tx, err){
                  Debug.log(err.message);
                  return true;
            });
        });
    },
    dbConnection : dbConnection
}
};

执行:

var DBFactory = {
getConnectionforApp: function(){
    try{
        var db_instance = new DB('mydb', '1.0', 'DB Connection 1', 1024*1024);
        Debug.log('Connected to db: '+db_instance.isConnected());
        return db_instance;
    }catch(e){
        Debug.log(e.message);
    }
}

};

// the example
var dbObj = DBFactory.getConnectionforApp();

alert(dbObj.tableExists('foo'));

当我执行这段代码时,公共方法tableExists给了我一个警告,即existingTables.length = 0,但是我在函数的对象的开头添加了这个数组中的所有现有表:checkTables( )。

  1. 为什么函数tableExists中的数组existingTables为空?
  2. 为什么函数tableExists在函数checkTables之前执行?
  3. 是否有可能制作一些construct()函数,在所有其他函数之前首先在对象创建时调用它?

1 个答案:

答案 0 :(得分:0)

解决方案是使用自己的回调函数。

这是一个正在运行的例子:

var Debug = function(){
var debug   = true;
var type    = 'console';

function timestamp() {
    var date = new Date();
    var year        = date.getFullYear();
    var month       = date.getMonth();
    var day         = date.getDate();
    var hour        = date.getHours();
    var minute      = date.getMinutes();
    var seconds     = date.getSeconds();
    var miliseconds = date.getMilliseconds();
    minute = (minute < 10) ? "0" + minute : minute
    seconds = (seconds < 10) ? "0" + seconds : seconds
    return year+'-'+month+'-'+day+' '+hour+':'+minute+':'+seconds+':'+miliseconds;
}

return{
    log : function(message){
        if(true == debug){
            switch(type){
                case 'console':
                    console.log(timestamp()+': '+message);
                break;
                case 'alert':
                    alert(timestamp()+': '+message);
                break;
                case 'document':
                    document.write('<br />'+timestamp()+': '+message);
                break;
            }
        }
    }
}
}();

var DB = function(dbName, dbVersion, dbDescription, dbSize){
var dbConnection    = null;
var is_connected    = false;

var dbName          = dbName;
var dbVersion       = dbVersion;
var dbDescription   = dbDescription;
var dbSize          = dbSize;

var existingTables  = new Array();

var connect = function(){
    Debug.log('call connect');
    if (!window.openDatabase) {
        Debug.log('SQLite openDatabase not supported');
        return false;
    }
    else{
        dbConnection = window.openDatabase(dbName, dbVersion, dbDescription, dbSize);
        is_connected = true;
    }
}();

function tableExists(table, callback){
    Debug.log('call tableExists');
    dbConnection.transaction(function (tx) {
        tx.executeSql('SELECT name FROM sqlite_master WHERE type="table"', [], function(tx, rs) {
            for( var i = 0; i < rs.rows.length; i++ ) {
                Debug.log(rs.rows.item(i).name);
                existingTables.push( rs.rows.item(i).name );
            }
          }, function (tx, err){
              Debug.log(err.message);
              return true;
        });
    }, null, function(){
        Debug.log('sql query call done');
        callback(checkTable(table));
    });
};

function checkTable(table){
    Debug.log('call checkTable');
    for(var i = 0; i < existingTables.length; i++) {
        if(existingTables[i] === table) {
            return true;
        }
    }
    return false;
}

// public methods
return {
    dbConnection : dbConnection,
    tableExists : tableExists,
    isConnected : function(){
        return is_connected;
    },
    tableCreate : function(table, callback){
        switch(table){
            case 'foo':
                var cr_sql = 'CREATE TABLE foo (id unique, text)';
            break;
            case 'bar':
                var cr_sql = 'CREATE TABLE bar (id unique, text)';
            break;
        }
        // create the missing table
        dbConnection.transaction(function (tx) {
            tx.executeSql(cr_sql, [], function(tx, rs) {
                    return true;
                }, function (tx, err){
                    Debug.log(err.message);
                    return true;
            });
        });
    }
};
};

var DBFactory = {
getConnectionforApp: function(){
    try{
        var db_instance = new DB('mydb', '1.0', 'DB Connection 1', 1024*1024);
        Debug.log('Connected to db: '+db_instance.isConnected());
        return db_instance;
    }catch(e){
        Debug.log(e.message);
    }
}
};

// the example
var dbObj = DBFactory.getConnectionforApp();

var table_exists = dbObj.tableExists('foo', function(exists){
Debug.log('Table foo exists: '+exists);
});

var table_exists2 = dbObj.tableExists('bar', function(exists){
Debug.log('Table bar exists: '+exists);
});