Picture

Hi, I'm Boopathi Rajaa.

Hacker, Dancer, Biker, Adventurist

Non-Sequential Execution - JavaScript

First thing you must understand about JavaScript is, it doesn't follow sequential execution of program code. As a matter-of-fact, people learn C (or) C++ (or) Java as their first language, and progressively, if they start fiddling with JavaScript, they end up writing C style code in JavaScript, which indeed, is a very bad quirk.

If you're one those geeks who started with C, you would be certainly like,

I'm an old hand at programming and came back recently to my old passion and am struggling to fit in this Object Oriented, Event driven bright new world.

And seriously, when you see the advantages of non-sequential behavior of JavaScript, there are times where it'd really get in the way of simplicity and re-usability.  And the question is how are we going to achieve smartness in writing code - that's easy to read and easy to reuse. Before we continue on this,

Sequential Execution:

Googling around would get you pretty good results about this topic. But, just for Pete's sake, let me explain it briefly. By definition, Programs start by executing the first line the compiler encounters and continue by executing the next lines sequentially. Also, the (i)th line is executed only after the (i-1)th execution is complete. You can just imagine how you would write procedures/flow-charts in your childhood.

Begin --> Input statement --> Process Input Line 1 --> Process Input Line 2 --> Echo Output --> End

Here, Processing doesn't start unless the execution of Input statement is complete, and so on. Let's not continue with this topic and get our attention to waver or let boredom get the better of us.

A critic's point of view:

Say, You're developing a web application with a feature to accept feedback from the user. Now, you'd expect it to work like this.

  1. Ask the user a question - What are your impressions of myProject ?
  2. Get input from user
  3. Send a POST request (ajax)
  4. Inform User "Thanks for the feedback"

And, to make it work with JavaScript, the WRONG method to do is,

    prompt("What are your impressions")
    get(input)
    ajax.post(input)
    inform("Thanks for feedback")

because, it simply doesn't work this way. And, the first thing that you do is to blame JavaScript - as the sickest language of all times. Once you learn some JavaScript, you'll slowly discover a model to make it work the way you want, which would possibly result in writing code like this,

    prompt("What are your impressions of myProject", function() {
        get(input, function() {
            ajax.post(input, function() {
                inform("Thanks for feedback");
             });
        });
    });
    //I hope, I did not make too many mistakes bringing the code
    //to its essential. The real thing would just be distracting.

and this isn't any better than swearing JavaScript in the first place, because, you'd start thinking about accomplishing sequences of  higher orders, where the resulting code would look like

    a(1, function(){
      b(2, function() {
        c(3, function() {
          d(4, function() {
            e(5, function() {
               f(6, function() {
                 g(7, function() {
                   FINALLY("F**K YOU!");
                 });
                });
              });
            });
          });
        });
      });
    });

Understanding the uncertainty principle

I believe "feedback webapp" to be a perfect example where non-sequential execution of JavaScript is no good and sync is good, because, contrary to the UI event handling, we must have each step finish before the next is executed. But the code is a Matryoshka doll construction, it is confusing and unreadable. Code re-usability would become difficult to achieve because of all the nesting and it is simply difficult to bring to the inner function - all the parameters needed, without passing them to each container in turn or eventually using the global evil. Also, I would've loved what my code returns, but the first container would've been finished well before the return code is available to the execution context.

Now, let's get back to the question. Writing code - easy to read, easy to reuse. A solution to that would've been a simple program 20 years ago, using C, and a dumb electronic board. The requirement, in-fact, is so simple, that, I've the impression that I must be missing the fundamental understanding of JavaScript and modern programming. Surely, technology is meant for using the fuel productively, and for an awesome language like JavaScript, the fact that it is unobtrusive wouldn't be so obvious. You've to dig into it, learn from the experts and accept the eccentric ways they follow with an open mind. Sigh. I know it's boring, let's conclude with something.

And we've a winner

JavaScript is not meant to be written in a way, where you expect sequential code execution. Read upon evented IO programming. This post would get a mile long if I start with the explanation of event driven models. All I want you to understand is that don't tend to write poor JavaScript code as discussed above to achieve something like that.

A simple solution to the "feedback webapp" - to make it work that way - with features like readability and re-usability of program code, would be to use something like async.js. Or you could build your own sequencer function. It would look something similar to this.

    function Sequencer(delay) {
      this.delays = [delay]
      this.functions = [];
      this.seq(0,function(){},0);
    }
    Sequencer.prototype = {
      run: function() {
        var that = this;
        setTimeout(function() {
          that.functions.shift();
          that.run();
        }, this.delays.shift());
      },
      seq: function() {
        var seq = function(pre, func, post) {
          this.delays[this.delays.length-1] += pre;
          this.delats.push(post);
          this.functions.push(func);
        };
        return function() {
          seq.apply(null, arguments);
        };
      },
    };


    var s = new Sequencer();
    s.seq(10, function() { dothat("hi"); }, 10);
    //etc...

This piece of code is shitty and untested, and it is only to give you an overview of how it can be done. You can incrementally program with some base and achieve what you want.