Roozbeh G
Roozbeh G

Reputation: 557

Does Javascript run lines of code in order? and finish processing then move on?

I am trying to write some code in Javascript for first time, and I am guessing I dont get something conceptually!

The following code for me works fine :

var db = new alasql.Database("db");
db.exec('CREATE TABLE IF NOT EXISTS Myonetwo;');

var aaa = db.exec('select * into Myonetwo from json("http://localhost:8080/app1")',[],function(res){
    db.exec('select * from Myonetwo;',[],function(bbb){

            console.log(bbb.length);    
        });
});

But this one which is the same but not function inside function embedded, Does not work.

var db = new alasql.Database("db");
db.exec('CREATE TABLE IF NOT EXISTS Myonetwo;');

var aaa = db.exec('select * into Myonetwo from json("http://localhost:8080/app1")');
var bbb = db.exec('select * from Myonetwo;');
console.log(bbb.length);

Also Is getting result as a function defined as one of arguments something usuall for all Javascripts?

Upvotes: 4

Views: 3426

Answers (4)

chriskelly
chriskelly

Reputation: 7736

As the others have said it's because javascript, or in this case, NodeJS is asynchronous in nature. The reason is because it's very efficient to delegate I/O tasks because they take much longer to execute than ordinary tasks.

I think it can be explained well with an analogy:

JavaScript is like a builder. Lets call him (or her) Bob.

Scenario 1 - equivilant to second example in question

Customer asks Bob to build a house.

Bob is too busy to do the work alone so he asks Joe, a brick layer to help.

Joe starts laying bricks.

In the meantime, Bob asks Paul the plumber to put pipes in the walls.

Pauls beings to lay pipes ... hang on .. there are no walls yet

[malfunction]

In JavaScript the code might look like this:

Joe.layBricks()
Paul.layPipes()

and that is basically what happens in your second example

Scenario 2 - equivalent to your first example

Bob tries again:

Customer asks Bob to build a house.

Bob asks Joe to lay some bricks.

But this time he tells Joe that when he is finished he must tell Paul (known as a callback) he is ready.

Paul already knows what he needs to do but just needs to know when he can do it.

Much better. The work will get done.

Now Bob can even ask painter Pat to paint the house when the plumbing is done in the same way.

The code looks like this:

Joe.layBricks(Paul.layPipes(Pat.paintWalls()))

Look familiar? (should be close to example 1)

How its done in other languages

An easy thing for Bob to do would be to carry out all the work himself but that would not be very efficient or scalable. That's how a lot of languages work. But NodeJS has a better way which is where callbacks come into play.

Other advanced languages allow you to define your own threads. But they are pretty complex and can be difficult to understand and maintain.

Upvotes: 2

agershun
agershun

Reputation: 4107

You can rewrite the code:

var db = new alasql.Database("db");
var res = db.exec('CREATE TABLE IF NOT EXISTS Myonetwo;\
     select * into Myonetwo from json("http://localhost:8080/app1");\
     select * from Myonetwo;');
console.log(res);

In this case AlaSQL will run all operators sequentially (even they are async) and save them into res variable.

In other case you need to rewrite the code with callback:

var db = new alasql.Database("db");
var res = db.exec('CREATE TABLE IF NOT EXISTS Myonetwo;');
var res = db.exec('select * into Myonetwo from \
     json("http://localhost:8080/app1")',[],function(){
        var bbb = db.exec('select * from Myonetwo;');
        console.log(res);
});

In your example you need to use callback only for the second line, because JSON() function in AlaSQL is async.

Upvotes: 2

humanityANDpeace
humanityANDpeace

Reputation: 4647

Yes Javascript does run lines of code in order. But is also contains asynchronous/deferred programming elements.

The concept can be looked up here https://developer.mozilla.org/en/docs/Web/JavaScript/EventLoop

It boils down to this:

console.log("a");
console.log("b");    // output will be a, b, c
console.log("c");

// output will be a, b, c

then again

console.log("a");
setTimeout(function(){
   concole.log("b");
},0);
console.log("c");

//output will be a, c, b

The reason is that the code to print "b" appears both times before console.log("c") but it is indeed not both times executed before. In the second case it is queued in the EventLoop via the window.setTimeout(function, timeout) function

Upvotes: 3

Jonathan.Brink
Jonathan.Brink

Reputation: 25413

This is because the exec function is asynchronous, so in your 2nd example the bbb assignment line will happen prior to the aaa assignment line finishing.

This is why exec has a callback function as it's last parameter.

In your first code snippit the timeline of events will be something like:

  • first exec call
  • some time passes...
  • first exec callback happens
  • second exec call executes
  • second exec callback happens

In this case you know that the second exec call will happen after the first exec call.

Your second code snippit's timeline will be:

  • first exec call
  • second exec call
  • either first or second exec call finishes (non deterministic)
  • either first or second exec call finishes (non deterministic)

You can see that this will have a bearing on your logic.

Here is a good article to learn more about asynchrounous programming: https://blog.risingstack.com/asynchronous-javascript/

Upvotes: 3

Related Questions