Javascript Global variable problem
First I know WebKit do not allow Make synchronous requests to SQLite database. And I'm start playing with it and tried to assign result to global variable "data". I still not sure if it's possible but want to ask you.
I'm created global object to store respond from DB
var data = {};
Here is DB class
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;
},
}
- And finally here is the problem:
$(function () {
db.init();
db.exec('SELECT * FROM errors;');
alert(Log.object_toStr开发者_开发百科ing(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
});
So the problem is I can't manipulate with "data" right after db.exec() call, but if I make alert() after transaction then data will populate with all information.
Any ideas how can I avoid it?
I would assume that you're making an asynchronous AJAX call, so your alert()
fires before the response is received.
EDIT: As @Nick noted, this is not AJAX, but is an issue with it being asynchronous.
I don't know anything about the API you're using, but it would seem as though your alerts should be inside the dataHandler
method:
dataHandler: function (transaction, results) {
// Handle the results
data = results.rows;
alert(Log.object_toString(data) );
alert(Log.object_toString(data) );
return true;
},
Or should be in some other function that is called from inside 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) );
}
The reason an alert()
in between makes it work, is that the pause gives the response a chance to return before the other alerts run.
The problem is that if you access data right after you called exec the dataHandler callback wasn't called yet. The only way to make sure that you actually received your data from the query is to handle it within the callback itself. For that you could redesign your class a bit to allow the exec function to actually also take a callback function that will be called as soon as the query was executed successfully, eg
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);
}
}
Then you can call your db.exec like this:
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);
});
精彩评论