0

私は現在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 の前に実行されるのはなぜですか?

他のすべての関数の前に、オブジェクトの作成時に最初に呼び出されるconstruct()関数を作成する可能性はありますか?

4

1 に答える 1

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);
});
于 2012-12-28T13:35:53.477 に答える