views:

179

answers:

3

There is array of objects, which are expanded with parallel ajax requests. When last request is done array should be processed. The only solution i see is:

function expandArray(objects, callback){
  number_of_requests=objects.length-1;
  for(i in objects){
    $.getJSON(request,function(){
                //expanding array           
                if(--number_of_reuests==0){
                  callback();
                }
              });
  }
}

But as requests are executed in parallel there is chance of race condition. Variable number_of_requests can be edited by two "threads" simultaneously. How to avoid chance of race condition?

+1  A: 

Isn't Javascript single threaded? The kind of condition you talk of wouldn't occur.

spender
Yes, you're correct. There is no issue here.
Tim Down
I've looked at JavaScript specification and there is nothing said that JavaScript implementations must be single threaded.
wagner
Some good answers on this issue: http://stackoverflow.com/questions/124764/are-mutexes-needed-in-javascript
itsadok
Actually ECMAScript is specified as being single threaded, however if you do an asychronous load you will get the callbacks in the order the loads complete.You can think of ES in the browser as just having a single event queue with any ES to be executed just being pushed onto the back of the queue, and each event being fired sequentially.
olliej
+1  A: 

Is it possible to rework your AJAX so that it all goes in one request? That part of the system will be the biggest bottleneck and can get tricky (as you've found out), so the less requests you make, the better.

The only other way I could think would be if each request mutated its related object, setting a flag value or something, and then you looped through all the objects to check if all the flags had been set yet.

nickf
A: 

It's more complex, but I would suggest using a third function to monitor the results. Something like this:

1) Start monitor - using an appropriate interval monitor (using an interval to test here is important - a simple loop would lock the JS engine up tight) the results of requests A and B.

2) Call request A.

3) Call request B.

4) Request B finishes - callback function sets a "B All Done!" value.

5) Request A finishes - callback function sets an "A All Done!" value.

6) Monitor recognizes that both requests are completed and calls function which uses data from both.

Worded more simply this is "dependencies" (multiple calls)to "monitor" (the function that checks dependencies) to "completion" (the action to take when all is ready).

You can create the callbacks and the completion function as nested functions to maintain encapsulation and reduce "little" in the global scope.

You can extend your dependencies as far as you like.

Jim Davis