Javascript Глобальная переменная проблема - PullRequest
1 голос
/ 11 ноября 2010

Во-первых, я знаю, что WebKit не позволяет делать синхронные запросы к базе данных SQLite. И я начал играть с ним и попытался присвоить результат глобальной переменной «data». Я все еще не уверен, возможно ли это, но хочу спросить вас.

  1. Я создал глобальный объект для хранения ответа из БД

    var data = {};
  2. Вот класс БД


var db = {
        mydb: false,
        init: function () {
            try { 
                if (!window.openDatabase) { 
                    alert('not supported'); 
                } else { 
                    this.mydb = openDatabase('test_db', '1.0', 'Test DB', 1024*1024*5); 
                }
            } catch(e) { 
                // Error handling code goes here. 
                if (e == INVALID_STATE_ERR) { 
                    // Version number mismatch. 
                    alert('Invalid database version.'); 
                } else { 
                    alert('Unknown error '+e+'.'); 
                } 
                return; 
            }
        },
        exec: function (query, params) {
            try {
                this.mydb.transaction(function(transaction) {
                    transaction.executeSql(query, params, db.dataHandler, db.errorHandler);
                });
            } catch(e) {
                alert(e.message);
            }
        },
        dataHandler: function (transaction, results) {
            // Handle the results
            data = results.rows;
            return true;    
        },
        errorHandler: function (transaction, error) {
            // returns true to rollback the transaction
            alert('Code: '+error.code+'\nMessage: '+error.message);
            return true;
        },
    }
  1. И, наконец, вот проблема:

$(function () {
    db.init();
    db.exec('SELECT * FROM errors;');
    alert(Log.object_toString(data) ); // this alert show empty object as I declared in first line 
    alert(Log.object_toString(data) ); // this one return object with responded data from database
});

Так что проблема в том, что я не могу манипулировать «данными» сразу после вызова db.exec (), но если я сделаю alert () после транзакции, тогда данные будут заполнены всей информацией.

Есть идеи, как мне этого избежать?

Ответы [ 2 ]

3 голосов
/ 11 ноября 2010

Я предполагаю, что вы делаете асинхронный AJAX вызов, поэтому ваш alert() срабатывает до получения ответа.

РЕДАКТИРОВАТЬ: Как заметил @Nick, это не AJAX, но проблема в том, что он асинхронный.

Я ничего не знаю об используемом вами API, но может показаться, что вашоповещения должны быть внутри dataHandler метода:

dataHandler: function (transaction, results) {
    // Handle the results
    data = results.rows;
    alert(Log.object_toString(data) ); 
    alert(Log.object_toString(data) );
    return true;    
},

Или должны быть в какой-то другой функции, которая вызывается изнутри dataHandler.

dataHandler: function (transaction, results) {
    // Handle the results
    data = results.rows;
    someFunction( data );
    return true;    
},

// ...

function someFunction( data ) {
    alert(Log.object_toString(data) ); 
    alert(Log.object_toString(data) );
}

Причина alert()промежуточное действие заставляет его работать, заключается в том, что пауза дает ответу возможность вернуться до запуска других оповещений.

1 голос
/ 11 ноября 2010

Проблема в том, что если вы обращаетесь к данным сразу после вызова exec, обратный вызов dataHandler еще не вызывался. Единственный способ убедиться, что вы действительно получили данные из запроса, - это обработать их внутри самого обратного вызова. Для этого вы можете немного изменить дизайн своего класса, чтобы позволить функции exec фактически также принимать функцию обратного вызова, которая будет вызываться, как только запрос будет выполнен успешно, например

exec: function (query, params, onSuccess /*, onFailure*/) {
    try {
        var onFailure = arguments[3] || function(){};
        this.mydb.transaction(function(transaction) {
             transaction.executeSql(query, params, onSuccess, onFailure);
        });
    } catch(e) {
        onFailure(e);
    }
}

Тогда вы можете вызвать ваш db.exec так:

db.exec('SELECT * FROM erros;', null, function(rows) {
    alert(Log.object_toString(rows));
}, function() {
    var error = arguments[0] || {message: 'Unknown Exception'};
    alert('An error occured: ' + error.message);
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...