Node.js
Lecture 05 — Data Engineering — Spring 2015
January 27, 2015
Hello World in Node.js
var http = require('http');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n');
}).listen(1337, '127.0.0.1');
console.log('Server running at http://127.0.0.1:1337/');
Taken from the Node.js Home Page
Explanation (1)
var http = require('http');
- Most code in node is packaged inside of a module
- http is a core module, provided by Node.js itself
- The require function will look for modules in a variety of locations
- built-in modules
- globally-installed modules
- project-specific modules
Explanation (2)
http.createServer(<function>).listen(1337, '127.0.0.1');
- http provides a function called createServer()
- It takes a function that implements the server's behavior
- createServer() returns an object with a method listen()
- It accepts the server's network interface and port
- It also starts the server running
Explanation (3)
function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n');
}
- This is the anonymous function passed to createServer().
- Each time the server receives a request
- It invokes this function and passes the HTTP request and response objects
- This particular function ignores all input and generates a simple HTTP response.
Explanation (4)
console.log('Server running at http://127.0.0.1:1337/');
- console.log() is the printf() of the Javascript world.
Explanation (5)
Our program in abstract form
1. Get the http module.
2. Create a server; register a function; start a server.
3. Print out a message.
- All of this is executed immediately when passed to node
- If no future work remained, node would shut down.
- This particular program, however, will run forever
- because the HTTP server has set up an event to check for new requests on every cycle of the event loop
Event Loop?
- In order to understand Node.js, you need to understand the event loop
- Event-based programming is a programming style where the code you write is not in control
- Instead, you write code that says (essentially)
"When event x happens, do this"
Event Loop (1)
The basic structure of all Node.js programs
while (there are events to be handled) {
handle event
}
This is how GUI programs are written.
"If user click here, do this."
Event Loop (2)
- Node tries to make it easy to add work to the event queue
- Libraries like http take functions and add them to the queue on your behalf (as we saw with createServer()).
- Node also lets you add functions to the event queue for later execution.
- process.nextTick()
- setImmediate()
- setTimeout()
- setInterval()
Event Loop (3) — process.nextTick()
A simple example using process.nextTick()
console.log("first!");
process.nextTick(function() {
console.log("third!");
});
console.log("second!");
- Our main program is simply a function passed to the event loop
- On the first pass: log(), nextTick(), log()
- On the second pass: log()
- Since there are no more events, the program ends.
Event Loop (4)
- Our program would behave the same if you replaced process.nextTick() with setImmediate()
- They both schedule a function for the next iteration of the event loop.
- The difference is that setImmediate() allows IO-related callbacks to process first.
- process.nextTick() will prioritize your function before IO-related callbacks, possibly causing IO starvation
Event Loop (5)
- setTimeout() takes a second parameter that specifies how long to wait before the function is executed.
- setInterval() take a second parameter that specifies the interval at which this function should be executed.
- If the interval is never turned off, the node program will execute "forever".
Callback Hell (1)
Callbacks are great for asynchronous programming, but...
It can lead to callback hell, where callbacks get indented
Callback Hell (2)
Here the callbacks have been highlighted...
Callback Hell (3)
- The problem occurs when you have to chain multiple asynchronous calls together
- Each call in the chain has to be in a callback on the previous function
- because you have to wait for the previous call to finish
- before you proceed
Callback Hell (4)
- Two ways to solve this problem:
- Use synchronous functions instead
- frowned upon by the Node community
- Use named callback functions
- Define your functions individually
- Then refer to them by name in the code that requires a callback
Callback Hell (5)
Fixing with Named Callbacks
Callback Hell (6)
Here the callbacks have been highlighted...
Just Callbacks?
- Are callbacks the only asynchronous mechanism in Node?
- No!
- We'll discuss these concepts next week
Node Execution Model (1)
- For user-written code, Node is single threaded!
- Any code that you write is guaranteed to be synchronous
- You do not have to worry about race conditions
- IO is handled in parallel.
Node Execution Model (2)
- If you issue an asyncrhonous call for IO
- Your callback is registered
- The IO call is executed in a separate thread
- Since it's an IO call, it immediately blocks
- Other events on the event loop are handled as normal
- At some point, the IO completes and your callback is invoked
- Invoked via setImmediate() or process.nextTick()
- So, even then, your code executes in a single thread
Node Execution Model (3)
- This model makes it very easy to implement services that run server-side.
- You are guaranteed that only one method of your service is running at any one time.
- You are now in a position to understand the Javascript implementation of the Contacts web service
Hands-On Demo
- Let's try a few things in class together
- Does everyone have Node installed?