TimothyP
TimothyP

Reputation: 21765

How to deal with async function results in JavaScript

Coming from a c# background, I'm probably looking at JavaScript from a completely wrong perspective, so please bear with me.

Leaving the advantages of async aside for a minute, let's say I simply want to retreive a value from an SQLite database in an HTML5 page. What I want to see is something like

var something = db.getPicture(1);

Now consider a (perhaps very naive) implementation of this:

this.getPicture(id)
{
    this.database.transaction(function(tx)
    {
        tx.executeSql('SELECT ......', null, function(tx, results)
        {
            if (results.rows.length == 1)
                return results.rows.items(0).Url; //This of course does not resturn
                                                    //anything to the caller of .getPicture(id)
        }
    },
    function(error)
    {
        //do some error handling
    },
    function(tx)
    {
        //no error
    });                     
}

First off, it's one big mess of nested functions and second... there's no way for me to return the result I got from the database as the value of the .getPicture() function.

And this is the easy version, what if I wanted to retreive an index from a table first, then use that index in the next query and so on...

Is this normal for JavaScript developers, am I doing it completely wrong, is there a solution, etc...

Upvotes: 2

Views: 518

Answers (1)

Pointy
Pointy

Reputation: 413976

The basic pattern to follow in JavaScript (in asynchronous environments like a web browser or Node.js) is that the work you need to do when an operation is finished should happen in the "success" callback that the API provides. In your case, that'd be the function passed in to your "executeSql()" method.

this.getPicture = function(id, whenFinished)
{
    this.database.transaction(function(tx)
    {
        tx.executeSql('SELECT ......', null, function(tx, results)
        {
            if (results.rows.length == 1)
                whenFinished(results.rows.items(0).Url);
        }
    },

In that setup, the result of the database operation is passed as a parameter to the function provided when "getPicture()" was invoked.

Because JavaScript functions form closures, they have access to the local variables in the calling context. That is, the function you pass in to "getPicture()" as the "whenFinished" parameters will have access to the local variables that were live at the point "getPicture()" is called.

Upvotes: 2

Related Questions