Friday, April 08, 2011

HTML5 Web Databases in Chrome, round 1

New fact of life: To keep up with modern web programming, you need to get your head around asynchronous callbacks. To illustrate, here is a quick script I wrote to experiment with Chrome's JavaScript calls into it's SQLite implementation:

var output = null;

function onSuccess(transaction, result) {
  output = result.rows.item(0).sql;
  console.log('onSuccess completed');
}

function getDB(dbName) {
  var fm = 5*1024*1024; // Five Megs
  var db = openDatabase(dbName, '1.0', dbName, fm);
  console.log('Database opened');

  this.runSql = function(sql) {
    db.readTransaction(function(t){
      t.executeSql(sql, [], onSuccess)
    });
    console.log('runSql completed');
  }

  return this;
}

var joe = getDB('db');
joe.runSql("select * from sqlite_master");
console.log('output: ' + output);
console.log('End of script');

Until it dawned on me that the SQL execution was asynchronous, I spent about 30 minutes chasing my tail trying to find a variable scope problem. In the console debugger, everything seemed to be set right when I manually entered commands one at a time, but the script didn't seem to be setting them when it ran. Didn't seem to be, but it just wasn't happening when I thought.

The above script was a re-write of what I was doing initially, with loggers at each step to show when the "output" variable gets set. Unsurprisingly, it happens on its own good time, not when the "procedural" part of the script reaches the end.

Here's a screenshot of the console output:



The value of "output" is still null when the script reaches its last line. Manually checking the value after onSuccess completes shows that it does get set correctly, just later. So, there you have it. Writing that iPhone app or new web game? Start thinking async.

No comments:

Post a Comment