Javascript Jems - Asynchronous Patterns
Thursday, 22 July 2010
Article Index
Javascript Jems - Asynchronous Patterns
An asynchronous example

If you have ever lain awake at night worrying about closure? We explain how it can be all so easy and really, really useful. Closure in Javascript was just made for  asynchronous code and for Ajax in particular.

Banner

Closure is usually regarded as an "advanced" feature of Javascript and correspondingly off putting. Even if you understand what it is and how it works it can be very difficult to see what it is useful for.

In fact it really is very simple and very useful.

What is a closure?

(If you already know about Javascript closure then skip to the next section, The Asynchronous Pattern.)

Put simply closure means that a local function has access to all of the variables declared at the same level – even if the enclosing function has terminated.

Think about this basic definition for a moment. A local function normally has access to everything defined at the same level as it. Everything that should be accessible from with in it is accessible from within it. No shocks or surprises yet. The part of the definition that is suprising is that it still has access to everything after the everything has in principle been destroyed.

The next puzzle is how can everything around a function have been disposed of but the function is still around? The only way that this can happen is if there is a refernce to the function from some other part of the program which is still active. That is the block of code that the function is defined in terminates and so no longer exists but the function is kept alive because there is a reference to it that lives on.

Let's look at the simplest possible example:

function MyOuterFunction(){
var a=123;
function MyInnerFunction(){
alert(a);
}
return MyInnerFunction;
}

If you read through MyOuterFunction you can see it declears a local variable which it sets to 123. It then defines a local function MyInnerFunction which simply displays the value of a. The inner function has access to the variable a because it is local to MyOuterFunction. So far nothing odd is going on. However when MyOuterFunction comes to an end it returns a reference to MyInnerFunction.

So if you now write:

f=MyOuterFunction();
f();

you will see closure in action. The first line stores a reference to MyInnerFunction returned by MyOuterFunction in f. The final line uses the function invocation operator i.e. () to call the function that f is set to. In this case it is MyInnerFunction and this displays an alert box with 123, the value of a in it.

Notice that there are two remarkable things about this example. The first is that the inner function exists and can be used after the outer function is long gone. The second is that the inner function has access to variables that were defined within the outer function even though they too are in principle long gone.

This is the a magic of closure.

The asynchronous pattern

The problem with closure is that it sounds complicated until you get the idea and once you have got it you can’t really see why anyone in their right mind would bother to implement it.

There are lots of reasons why closure is a good idea but one of the most useful and practical concerns writing asynchronous code.

In an asynchronous environment it is tempting to try to impose order simply by making the initiating thread wait for the asynchronous task to complete.

For example, suppose you have a function that loads some resource asynchronously. The logic is usually something like

  1. start the resource load asynchronously
  2. when the resource is loaded do something with it.

The problem here is what does the thread that started the resource load do while it is being loaded?

The simple-minded approach is to make it wait:

  1. start the resource load asynchronously
  2. loop until resource ready
  3. do something with resource

If you try this in JavaScript, and it can be done, the result is that you lock the main UI leaving the user with an unresponsive browser while the resource loads.

You also have to include the possibility that the resource will never succeed in loading. This complicates the logic over what can be achieved using a proper asynchronous approach because when a resource doesn’t load for any reason either you want to do nothing or attempt a reload.

An asynchronous approach “does nothing” by default when a resource doesn’t load because the “onload” event handler is never called. Similarly dealing with a non-load event is usually just a matter of hooking into the correct error event handler.

To achieve the same result using polling you have to include a test for a timeout and add code to handle the result:

start the resource load asynchronously

  1. loop until resource ready or time out
  2. if not time out then
       do something with resource

    else

       do nothing or reload resource

    end if

Next we'll consider the alternative asynchronous approach.

Banner

<ASIN:0470684143>

<ASIN:0137054890>

<ASIN:0470526912>

<ASIN:1449381871>

<ASIN:1430230541>

<ASIN:0321683919>



Last Updated ( Monday, 09 August 2010 )
 
 

   
RSS feed of all content
I Programmer - full contents
Copyright © 2014 i-programmer.info. All Rights Reserved.
Joomla! is Free Software released under the GNU/GPL License.