From null with love

A website for engineering, code and programmer livestyle.
Dec 10, 2012

In my current work, I have joined with two friends to create a new project, what requires a web that (obviously) uses javascript of the client side. One of my colleagues is a great programmer but he didn't know javascript. He asked me a set of good questions that, sincerely, I asked when I started javascript and nobody answered me. That's why I thought to answer them.

The next conversations are real, although I have simplified the code and I have summarized the content. He always works with jQuery library.

Understanding the asyncronous way

My friend: - I don't understand it… Why doesn't work my code? Hum…
Me: - What do you want to done?
My friend: - I want to download the content of the an url with ajax using the jQuery's post() function.
Me: - Can I look your code?
My friend: - Absolutely! Here is:

var content;
/* stuff … */
$.post("/myurl",{},function(data,textStatus){
        content = data;
        /* more stuff… */
});
console.log(content);
/* more code that uses "content"... */

My friend: - The console.log() line should returns the content of the url, right?
Me: - …but returns undefined, isn't it?
My friend: - Exactly! Why?
Me: - Hum…Do you know that the post() function is asyncronous?
My friend: - Yes, I know it. The function(data,textStatus) returns the content when it is downloaded…
Me: - …Then, when does the result of the function return? What do you think about the next lines of the function?
My friend: - Hum… the next lines are syncronous and they use the result, then this lines don't work while ajax works.
Me: - No! You should think as the asyncronous threads and javascript works. You can imaginate the javascript interpreter as a machine that never rests. All tasks are saved by an heap expends some time for each one of them.
Javascript interpreters the line of the post:

$.post("/myurl",{},function(data,textStatus){

OK, javascript knows that this task is asyncronous. So javascript saves the task in its heap and continues interpreting.

console.log(content);

Mmm… OK, javascript hasn't a value for this now: undefined. This happens because Javascript hasn't finished the post() function yet. Javascript continues executing code…
(Ten seconds of hard download after…)
OH! The post() function has finished. So javascript can execute the callback function:

function(data,textStatus){
        content = data;
        /* more stuff… */
}

Content is now defined: its value is "data", so you can use in this context.
My friend: - Ok,ok… so… if I want to use asyncronous content, ALWAYS should use inside the callback function.
Me: - Exactly.
(Five minutes of obscene thoughts after…)
My friend: - Although I could use a sleep() function to wait to the download of this content too…
Me: - Never!!! If you did this, you know nothing, John Snow. In a syncronous task, javascript waits to finish it to continue with the other functions. So, If you force to javascript to realise sleep(), the other functions wait in the heap won't be executed until the time of sleep() finishes, whereby syncronous sleep() does not works never.
[BONUS for the readers: try to create a syncronous function to sleep() in javascript and verify the result :)]
My friend: - Aaaaaaah…ok,ok…

Using the functional programming principles

My friend: - Ok, finally I think I have understood the javascript asyncronous way. But it is the ugliest code I've ever seen.
Me: - Why?
My friend:- I have to download three contents of the different urls. Look my code:

$(function(){
    $.post("/myurl1",{},function(data1,textStatus){
        content = data1;
        /* more stuff with data1… */
        $.post("/myurl2",{},function(data2,textStatus){
            /* more stuff with data2… */
            $.post("/myurl3",{},function(data3,textStatus){
                /* more stuff with data3… */
            });
        });
    });
});

Me: - Mmm…it seems too complicated, isn't it? There are other forms to express this:

$(function(){
        var isDownloadedThirdContent = 
        function(data,textStatus){
            /*more stuff with data3… */
        };
    
        var isDownloadedSecondContent = function(data,textStatus){
            $.post("/myurl3", {}, function(data,textStatus){
            
            });
        };
        
        var isDownloadedFirstContent = function(data,textStatus){
            $.post("/myurl2",{},function(data,textStatus){
                /*more stuff with data2…*/
            });
        };
        
        var init = function(data,textStatus){
            $.post("/myurl3",{},function(data,textStatus){
                /*more stuff with data1…*/
            });
        };
                
        init();
});

My friend: - I don't understand nothing.
Me: - In this code, we have ordened the functions in different variables. You should understand the functional programming if you want to program seriosly with javascript. In functional programming, Functions are first-class citizens. This means functions can be (and usually are) variables, parameters of another functions, and results of functions. A example is the $.post()function you are using:

$.post(direction,params,callback)

where callback, is a function what is executed when the post request is finished.
This other example explain some of the posibilities of the functional programming:


var apply = function(a,b){
    return a(b); //where a is a function and b a parameter.

};

var concatenate = function(a,b){
  return a + b;
}

var Bconcatenate = function(a){
    return concatenate("b",a); //Bconcatenate apply partially the concatenate function.
}

apply(Bconcatenate,"a");

//returns "ba";

My friend: - Ok, I think that the functional programming is too difficult for me. Can I go on by the "normal" way?
Me:- You could go on with imperative programming to develop scripts with javascript, but you should get used to it. Functional programming is fun! And you can improve your scripts with some lines of code. Also it is usually more cleaner than the imperative javascript.
My friend: - Then I'm going to start reading some books about functional programming…

Conclusion

What is the result of these conversations? My friend knows the functional programming and the real effects of the asyncronism. If another programmers (as me) wouldn't have been this before, probably the first year of javascript programming wouldn't be a such horrible experience.