I’m doing a lot of phone development recently. The biggest change that this has made to my style of coding, is that it means I’ve had to learn asynchronous coding methods, which I didn’t have to do when my code was mostly server-based.
For instance, on a server in PHP, when you retrieve a database item, the retrieval is “synchronous”. This means that when you run something like the following pseudocode, line 2 will definitely happen after line 1 has finished:
1. get data from database 2. print data to screen
However, the local databases in HTML5 (indexeddb) is asynchronous. This means that you make a request, and it goes off on its merry way and might not come back for a while, and meanwhile, your program continues immediately to the next line.
In asynchronous coding, we have a problem called “race conditions”. The problem is that we cannot be sure when the asynchronous code will be finished its job, so need to think outside the box in order to make our job bullet-proof.
Using the pseudocode above, line 2 will be reached alright in an asynchronous system, but it will very probably fail, as line 1 will probably not yet be finished.
The solution in a simple case (retrieve one item, then do something), is to use a “callback” function. This is a function that the code is to run after the retrieval has finished.
We can rewrite the first example like this then:
1. get data from database, with the following callback: 1. print the data to the screen
That’s a simple case, and easy to understand.
File access in HTML5 is also asynchronous, and throws up another problem.
With a database, you can write a query such that multiple rows of data are returned at the same time. But with file access, if you want to get the contents of multiple files, you need to access each file independently. The problem is that each of these is a new asynchronous process.
The solution is to have a count-down, which you set to the number of items to be retrieved, and as each item is retrieved, decrement the count-down. If it hits 0, then you have all the information you wanted and can call the callback.
Here’s how it would look in synchronous code (on a server, for example)
1. foreach file, retrieve the file 2. do whatever is next
and here is the asynchronous version:
1. set $leftToGet to the number of files to retrieve 2. foreach file: 1. retrieve file, and when it's retrieved: 1. reduce $leftToGet by 1 2. if $leftToGet is 0, then do whatever is next
I know it looks really simple when I write it like that, but when you’re used to synchronous code, its not obvious at all!