Stefan
Stefan

Reputation: 2613

Javascript Asynchronous success function - mutex

consider the following situation:

In order to have lots of work processed at my backend I send data to an interface and wait for the resulting data to return. Therefore ajax calls are just perfectly. Because of not knowing, in what order the result is received, and I need the results in specific order before I can display anthing, I will have a function only be called, if all sent tasks where returned correctly. This could be done through a simple (reduced, not exactly) semaphore variable that counts how many tasks were sent.

    var tasks = 0;

    do {
    // things to prepare
    tasks++;

    $.post("foo.php",data, function(data) {
    tasks--;
    foo(data); 
});

    }while(thereIsMore);

    foo(data) {

    // push data to array
    // sort the array

    if(tasks == 0)
     processResults(array);

    }

Javascript is called to be single tasked, not multi tasked. Am I really right to say, that there cannot be any situation to have mutual exclusion on accessing the array and the tasks counter because it will never happen? I am a bit confused of the asynchronous behaviour and may think of scenarios where racing situation could be given?

An example (and what my understanding is):

3 Tasks where sent out and received in a very small time frame. All responses are handled therefore in a type of scheduling. Task 1 has checked (if tasks==0) and it was false. Task 2 is paused one instruction before checking the tasks and task 3 is now executed as success handler. Task 3 now decrements tasks and its value is 0. Task 3 is paused and Task 2 is resumed. Task 2 checks if(tasks==0) and hell yeah.. it is zero. It starts processing, but not all data is in the array and sorted.

I am very interested in your opinion or knowledge, if this is totally insane sh*t that is not possible to happen. Share your knowledge please :-)

Upvotes: 0

Views: 4270

Answers (3)

Uzair Farooq
Uzair Farooq

Reputation: 2427

Such racing conditions can never occur in javascript. There's is this thing in javascript called Run-to-Completion which ensures that if a code is executing it executes completely before any other (asynchronous) code runs, hence, no concurrency issues.

See Why no concurrency control tool in javascript for more details.

Upvotes: 0

Greg Ross
Greg Ross

Reputation: 3498

You could also just use JQuery's "when()" method with deferreds.

...or, Underscore's "after()" function.

Either of these provide a really simple way to keep track of when a number of asynchronous requests have returned.

Upvotes: 0

jfriend00
jfriend00

Reputation: 707436

Only one ajax response function will ever run at a time and it will run to completion before the next one can be run. You do not have to worry about simultaneous access to your javascript variables - it cannot happen. Javascript in a browser is truly single-threaded (except for Web Workers, but that's not what we're discussing here).

Javascript uses an event queue. When an asynchronous operation like an ajax call completes, it puts an entry in the event queue. If no javascript is currently executing, that event is fired immediately (and the ajax callback is called). If some javascript is currently executing, it just keeps executing. When javascript finishes a thread of execution, it checks to see if there is anything else waiting in the event queue. If there is, it processes that event. This is the same way that mouse events, keyboard events, timer events, ajax completion events, etc... work.

The next event only gets processed when the current thread of execution has finished.

If you want to know when all your ajax calls have completed, you can just keep a count of how many ajax calls have completed so far like in your example code. In each completion function, you change the completion count and compare its value to see if all are done. If the number indicates that all of them are done, then you can carry out your final operation. If they are not all done yet, then you store the data and do nothing else because the last success handler will see that they are all done and initiate your final action.

Upvotes: 1

Related Questions