In this case, http has just one important thing that it can do, and that is create a web server using the http.createServer();
function call. That function call contains another boatload of JavaScript information and, equally as important, information
about how Node.js expects you to write it for everything to work properly. The line of code without the meat in the middle is
http.createServer(function (req, res) {});.
Yes, this really is a function that takes a function as an argument. In JavaScript, even a function is an object. The closest
comparison in .NET-land would be a delegate, which is an object wrapper around a function.
Note
I actually said that backwards. The fact is every object in JavaScript is declared as a function. I’ll get to this, too, very
shortly. I do realize that if all you have done with JavaScript up until this point is hide and show some divs with JQuery,
this is fairly mind-expanding stuff. I’ll keep it as simple as I can and let you run with the rest when you’re ready.
Let’s get back to our one line of wondercode:
Click here to view code image
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n');
}).listen(1234, '127.0.0.1');
The special thing about JavaScript and passing functions to functions (such as function A as an argument to function B) is that
function B doesn’t actually use that function per se or anything that it does. Instead, it wires that function as a callback.
A callback function is basically the same as a callback from your local phone company. If you call the phone company (if
it’s a modern phone company, that is) when customer service is busy, you will get an option to leave your number and have the
company return the call or “call you back” when they are ready to service you. In other words, they’ll call you when they are
done doing whatever else they were doing before they could get to you. The callback function A receives the result of function
B and then can act upon that result.
This concept, using callback functions in every action you take in JavaScript, is the essence of Node.js programming. It
creates what is known as the asynchronous model of code.
Something is synchronous if it always runs in order, A and then B and then C. But if B is a callback function, meaning it
begins to run only when function A has some final result for it to start working on, then C could run after A finishes but before
B is done running, making the code asynchronous:
Click here to view code image
obj.myFunctionA(functionB (x) {});
obj.myFunctionC();
Just passing an argument that JavaScript thinks is an object like any other (!) doesn’t stop code from running. So the
JavaScript processor (which could be the subject of a whole book on its own if it isn’t already) thinks that function A is done
when whatever is in its brackets is done running. It couldn’t care less about the fact that function B hasn’t yet finished doing
what it needs to do before function C goes ahead and leaves the starting gate.
Despite whatever complications this idea introduces to your code and data logic, it contains a tremendous amount of power
and potential. At its most basic level, if function A is a web request and function C is also a web request, then C does not have
to wait for the results of A (meaning B) to finish processing or rendering before beginning to run. As long as B, which is now
running in its own little universe, is not touching any resources common to C, by following this model cleverly enough you can
conceivably craft a way to spin a huge number of concurrently running universes, all processing their own requests in their own
space. They are completely independent of any other resource and serve up webpages at the absolute optimum speed for each
one.
All of this helps explain some of the anecdotal evidence I referred to at the beginning of the book, and it explains why we
have Node.js in the first place. The widespread use of the callback model creates asynchronous processing of web requests,
and it can have a huge positive impact on performance.
That’s really all it is. After that, you do everything by hand to fit the model. Doing this, of course, would be practically
impossible on a day-to-day commercial basis when compared dollar-for-dollar against almost anything with prebuilt toolkits
containing everything from controls to styling to database connections and more. Hence, you see an explosion in the number of
npm packages to bring those development times more in line with other approaches and, thus, the current state of Node.js
development.