Reputation: 557
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
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.
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
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)
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
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
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
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:
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:
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