Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaScript synchronization options

I was wondering whenever exists a solution to perform synchronization in JavaScript code. For example I have the following case: I'm trying to cache some response values from AJAX call, the problem is, that it's possible to perform simultaneously several calls, therefore it leads to race condition in the code. So I'm very curious to find solution for that? Any one has idea that to do?

like image 456
Artem Barger Avatar asked May 09 '09 10:05

Artem Barger


People also ask

What are synchronous operations in JavaScript?

Synchronous code runs in sequence. This means that each operation must wait for the previous one to complete before executing. console.

Can you make JavaScript synchronous?

Well, Javascript is Synchronous, It is a synchronous, single-threaded language. Because it has a single thread that's why it can only execute one command at a time and the other commands need to wait for executing before the running command executes.

Is JavaScript synchronous or async?

Spoiler: at its base, JavaScript is a synchronous, blocking, single-threaded language. That just means that only one operation can be in progress at a time. That's not the entire story, though!

Is JavaScript by default synchronous?

JavaScript is synchronous by default and is single threaded. This means that code cannot create new threads and it will execute your code block by order after hoisting.


3 Answers

I can offer a possible solution, but without seeing the code ... not completely sure what you are doing, but there is no reason why you couldn't do this.

Basic code in jQuery : (not tested and abbreviated ... but I have done things similar)

var needAllThese = {};

$(function(){

      $.ajax("POST","/somepage.aspx",function(data) {
          needAllThese.A = "VALUE";
      });

      $.ajax("POST","/somepage2.aspx",function(data) {
          needAllThese.B = "VALUE";
      });

      $.ajax("POST","/somepage3.aspx",function(data) {
          needAllThese.C = "VALUE";
      });

      startWatching();
});

function startWatching() {
   if (!haveEverythingNeeded()) {
       setTimeout(startWatching,100);
       return;
   }
   everythingIsLoaded();
}

function haveEverythingNeeded() {
    return needAllThese.A && needAllThese.B && needAllThese.C;
}

function everythingIsLoaded() {
   alert("Everything is loaded!");
}

EDIT: (re: your comment)

You're looking for callbacks, the same way jQuery would do it.

   var cache = {};

   function getSomeValue(key, callback) {
       if (cache[key]) callback( cache[key] );

       $.post( "url",  function(data) {
           setSomeValue(key,data);
           callback( cache[key] );
       }); 
   }

   function setSomeValue(key,val) {
        cache[key] = val;
   }

   $(function(){       
        // not sure you would need this, given the code above
        for ( var i = 0; i < some_length; ++i)  {
            $.post( "url", function(data){ 
                setSomeValue("somekey",data); 
            });
        }

        getSomeValue("somekey",function(val){            
             $("#element").txt( val );              
        };            
    });
like image 188
Chad Grant Avatar answered Oct 14 '22 14:10

Chad Grant


Javascript is inherently single-threaded, at least for the normal browser environment. There will never two simultaneous executions of scripts accessing the same document. (the new Javascript worker threads might be an exception here, but they're not meant to access documents at all, just to communicate by message passing).

like image 27
fforw Avatar answered Oct 14 '22 14:10

fforw


I have found solution for my problem. I have to say it's not that perfect as I was looking for, but so far it works and I think about that more as temporarily work around.

$.post( "url1", function( data)
{
     // do some computation on data and then
     setSomeValue( data);
});

var setSomeValue = ( function()
{
    var cache = {};
    return function( data)
    {
        if ( cache[data] == "updating")
        {
             setTimeout( function(){ setSomeValue( data);}, 100);
             return;
        }
        if ( !cache[date])
        {
             cache[date] = updating;
             $.post( "url2", function( another_data)
             {
                  //make heavy computation on another_data
                  cache[data] = value;
                  // update the UI with value
             });
        }
        else
        {
             //update the UI using cached value
        }
    }
})();
like image 27
Artem Barger Avatar answered Oct 14 '22 14:10

Artem Barger