views:

89

answers:

3

I'm using the Web SQL API to store some information on a page; I'd like to save the state of the page when the user closes the page or navigates away, thus, I start with:

window.onunload = function () {
  db.transaction(function (tx) {
    executeSql("INSERT INTO State (foo) VALUES (?)", [foo]);
  });
};

However, this is asynchronous so it doesn't complete before the page goes away.

I solve this unsatisfactorily by adding a (disingenuous, since it hasn't happened yet) alert("Saved!"); at the end of my window.onunload, which delays the unload until the DB has a chance to do its thing, but I'd rather not have that alert if I can avoid it.

Any ideas? I need to sort of block the thread calling the onunload function for a moment, which is what the alert does.

(BTW, to head off any suggestion that I use the synchronous openDatabaseSync version, that API is speced and implemented only for Web Workers, not for the Window object.)

+1  A: 

Do you have access to WebSockets?

Could you listen on a socket, and then when it's time to unload you connect to that listening socket, synchronously. When the listener receives a connection, it starts the insert and closes the connection after the query is done.

This is the only thing I could think of, and I am not sure that these interfaces support this kind of usage. I approached this by thinking how I would do this if I had a server: I would use a synchronous network connection to the server to write the state.

Also, I am not sure that the unload event can be blocked for an indeterminate length of time, but some Googling for "unload synchronous ajax" suggests it could be.

Update 7/19 10:26pm PDT

Browser WebSockets are send-only, you can't open a socket for listening.

Jesse Dhillon
Thanks for the idea, anyway.
Grumdrig
A: 

I'll just mention for posterity that another idea I've come across is to open a modal dialog with a timeout, like this:

window.showModalDialog('javascript:document.writeln ("<script>window.setTimeout(function () { window.close(); }, 100);</script>")');

But that's not completely cross-platform, perhaps. And the dialog window is visible in some browsers (Safari at least).

Grumdrig
My own answer seems to be the best I can do.
Grumdrig
A: 

There is reportedly a way of making SQL calls synchronous.

Synchronous Web SQL is part of the Web SQL specification draft. However this part is the one that was not implemented in any browser yet. And the specification draft is not going anywhere, because there is just one DB - SQLite.

However the fair folks in appcelerator somehow did the trick. Damn if I know how they did it though. If you can figure it out, please update this thread.

Michael
The synchronous API is not intended to be implemented in the browser, but for web workers only, so that's not going to happen. The syntax in Titanium doesn't seem to match that of the HTML5 spec, so I suspect they've done their own SQL implementation rather than using the HTML5 one. Or that's the only explanation I can think of.
Grumdrig