Print

Print


 The following is speculation only lightly leavened by experience.

Here's a simplified example:

     for (i=0; i<10; i++)
        {
         var thisArg =  ...  foo[i].innerHTML ... ;
         // alert("test") ;
         $.getJSON ( "http://somelibrary.org/q=" + thisArg +
"&jsoncallback=?",
                     function(data) {
                                    foo[i].innerHTML = data.bah
                                    }
                   )
         }

Now, the call to function(){} above creates a function closure, which is a
function object linked to its scope.  Because Javascript doesn't have block
scope (doesn't create a new scope for each block), the scope of all the
variables/code in the example above is the same.

What you'd like to happen in the example above is for the $.getJSON function
to be called and the request sent for i=0, then a result returned from the
remote site and the callback called, then the loop start again with i=1, and
so on.

What really happens is that Javascript is faster than the network, so the
browser runs through the loop, sending out 10 (asynchronous) requests, and
at the same time the results start to come back.  The problem is that the
callback functions for all 10 requests are bound to function closures that
share the same scope, and in particular share the variable "i".  This means
that the callback function calls collide with the loop that's sending out
requests.

When you included the call to alert(), you slowed things down so that the
first result did come back before the second request went out, the second
result before the third request, and so on.

I recommend that you try something like this:

   function goAndGetIt(thisElement)
      {
      var thisArg = ... thisElement.innerHTML ... ;
      $.getJSON ( "http://somelibrary.org/q=" + thisArg + "&jsoncallback=?",

                       function(data) {
                                      thisElement.innerHTML = data.bah ;
                                      }
                )
      }

   for (i=0; i<10; i++)
      {
      var thisElement = foo[i] ;
      goAndGetIt(thisElement) ;
      }

Each time you call goAndGetIt a new scope is created (with its own copy of
thisElement), so each function closure has its own scope.

Let me know if you'd like a more fully-worked out sample solution for your
problem.

Graeme Williams
Friend, patron & booster
Waltham Public Library
Waltham, MA