Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Intro to Node

Intro to Node

My Intro to Node talk at CodeShow.1 in Charleston, SC. I talk about what node is, how non-blocking I/O works, give a solid review of JavaScript semantics, promote small modules, etc.

Tim Caswell

March 14, 2013
Tweet

More Decks by Tim Caswell

Other Decks in Technology

Transcript

  1. About Me Long time Node.js contributor. Created howtonode.org. Spoken at

    over a dozen JavaScript and node.js conferences around the world. Started over a hundred open source projects on github. I love teaching programming and new tech! @creationix
  2. What is Node.js? Node.js is a platform built on Chrome’s

    JavaScript runtime for easily building fast, scalable network applications. Node.js uses an event-driven, non- blocking I/O model that makes it lightweight and efficient, perfect for data-intensive real-time applications that run across distributed devices.
  3. What is Node.js? Node is the scripting interface to your

    operating system. It’s especially useful for anything that involves heavy I/O It’s built using a fast JavaScript engine bound to an efficient event-loop library.
  4. I/O Latency L1: 3 cycles L2: 14 cycles RAM: 250

    cycles DISK: 41,000,000 cycles NETWORK: 240,000,000 cycles
  5. I/O Latency L1: 3 cycles L2: 14 cycles RAM: 250

    cycles DISK: 41,000,000 cycles NETWORK: 240,000,000 cycles
  6. I/O Latency (In Human Terms) L1: Grabbing a paper from

    your desk. (3 seconds) L2: Getting a book from the shelf across the room. (14 seconds) RAM: Walking across the office. (4 minutes) DISK: Roaming the Earth for 16 months! NETWORK: 7 year journey.
  7. Creating a TCP Server // Load the built-in tcp/socket library.

    var net = require('net'); // Create a plain socket server that echoes input. var server = net.createServer(function (socket) { socket.write('Echo server\r\n'); socket.pipe(socket); }); // Bind and listen on a TCP port. server.listen(1337, '127.0.0.1');
  8. Creating an HTTP Server var http = require('http'); // Create

    a server instance that accepts http connections var server = http.createServer(function (req, res) { // Respond to every request with the same message. res.writeHead(200, { 'Content-Type': 'text/plain', 'Content-Length': 12 }); res.end('Hello World\n'); }); // Start the server listening on a TCP port. server.listen(1337, '127.0.0.1');
  9. Working with Child Process var spawn = require('child_process').spawn; var ls

    = spawn('ls', ['-lh', '/usr']); ls.stdout.on('data', function (data) { console.log('stdout: ' + data); }); ls.stderr.on('data', function (data) { console.log('stderr: ' + data); }); ls.on('close', function (code) { console.log('child process exited with code ' + code) });
  10. Buffered File I/O var fs = require('fs'); // Buffered file

    reading fs.readFile('/etc/passwd', function (err, data) { if (err) throw err; console.log(data); }); // Buffered file writing fs.writeFile('message.txt', 'Hello Node', function (err) { if (err) throw err; console.log('It\'s saved!'); });
  11. Streaming File and TTY I/O // Simple `cat` implementation var

    input = fs.createReadStream("input.txt"); input.pipe(process.stdout); // Redirecting stdin to a file var output = fs.createWriteStream("output.txt"); process.stdin.pipe(output); process.stdin.resume();
  12. Streaming File Events var input = fs.createReadStream("myfile.dat"); input.on("data", function (chunk)

    { console.log("data", chunk); }); input.on("end", function () { console.log("end"); }); input.on("error", function (err) { console.error(err.stack); });
  13. Timers in Node.JS // Delayed Hello World using a timeout.

    setTimeout(function () { console.log("World"); }, 1000); console.log("Hello");
  14. Interactive Prompt var readline = require('readline'); var rl = readline.createInterface({

    input: process.stdin, output: process.stdout }); rl.question("What is your name? ", function(name) { console.log("hello", name); rl.close(); });
  15. Single-Purpose Modules Do one thing and do it well. Many

    modules export a single function or API endpoint.
  16. Single-Purpose Module // log.js module.exports = function (app) { //

    Do server setup stuff here. return function (request, respond) { // Do request setup stuff here. app(request, function (code, headers, body) { // Do response hooks here. console.log(request.method, request.url, code); }); }; };
  17. Single-Purpose Module // server.js var app = function (req, res)

    { res(200, { "Content-Type": "text/plain" }, "Hello World\n"); }; // Use the logging module app = require('./log.js')(app);
  18. Async Functions / Callbacks The non-blocking version of a function

    call. Eventually outputs a value (return) or fails with an error (throw) fn(arg1, arg2, function (err, res1, res2) { ... })
  19. Async Function Example var fs = require('fs'); // Buffered file

    reading fs.readFile('/etc/passwd', function (err, data) { if (err) throw err; console.log(data); }); // Buffered file writing fs.writeFile('message.txt', 'Hello Node', function (err) { if (err) throw err; console.log('It\'s saved!'); });
  20. Wrapping Async Functions function readCaps(path, callback) { fs.readFile(path, "utf8", function

    (err, text) { if (err) return callback(err); callback(null, text.toUpperCase()); }); }
  21. Doing Serial Actions function getUserFile(userID, callback) { // Start an

    async database lookup getFilename(userID, onGetFilename); function onGetFilename(err, filename) { if (err) return callback(err); // Start an async file operation readFile(filename, onReadFile); } function onReadFile(err, data) { if (err) return callback(err); callback(null, filename, data); } }
  22. Doing Serial Actions // Or for simple cases, use nested

    callbacks. function getUserFile(userID, callback) { getFilename(userID, function (err, filename) { if (err) return callback(err); readFile(filename, function (err, data) { if (err) return callback(err); callback(null, filename, data); }); }); }
  23. Doing Parallel Actions function getPageData(pageID, authorId, callback) { var page,

    author; loadPage(pageId, function (err, result) { if (err) return callback(err); page = result; if (author) callback(null, page, author); }); loadAuthor(authorID, function (err, result) { if (err) return callback(err); author = result; if (page) callback(null, page, author); }); }
  24. Event Emitter s Represent events that may happen zero or

    more times. A single emitter may emit different types of events. The “error” event is special and must be handled or it will crash. Usually represent human interaction or stream events.
  25. Readline Event Example rl.on('line', function(line) { switch(line.trim()) { case 'hello':

    console.log('world!'); break; default: console.log('Unexpected `' + line.trim() + '`'); break; } rl.prompt(); }).on('close', function() { console.log('Have a great day!'); process.exit(0); });
  26. Making You Own Emitter // Creating your own EventEmitters is

    easy var EventEmitter = require('events').EventEmitter; var bob = new EventEmitter(); bob.on("speak", function (message) { console.log("Bob says " + message); }); bob.emit("speak", "Hello World");
  27. Creating Custom Emitters // Create your own class that inherits

    from EventEmitter function JoyStick(id) { // Call the super constructor EventEmitter.call(this); // Do your own custom logic too this.openDevice(id); // ... } Joystick.prototype.__proto__ = EventEmitter.prototype;
  28. Streams Streams are a special EventEmitter with a predefined interface.

    Streams represent a stream of data, usually through a network socket or file I/O. Streams can be piped together like Unix commands.
  29. Closures and Objects Understanding how functions and closures work in

    JavaScript is essential to understanding Streams represent a stream of data, usually through a network socket or file I/O. Streams can be piped together like Unix commands.
  30. Local Variables // Let's create some local variables in the

    top scope var name = "Tim Caswell"; var age = 30; var isProgrammer = true; var likesJavaScript = true; // Test to see if the two variables are the same. isProgrammer === likesJavaScript; //-> true
  31. Global Variables var name = "Tim Caswell"; var age =

    30; var isProgrammer = true; // Oops we forgot a var statement! likesJavaScript = true;
  32. Objects and Inheritance // Create a parent object var tim

    = { name: "Tim Caswell", age: 28, isProgrammer: true, likesJavaScript: true } // Create a child object var jack = Object.create(tim); // Override some properties locally jack.name = "Jack Caswell"; jack.age = 4; // Look up stuff through the prototype chain jack.likesJavaScript;
  33. Closure Objects function makeClosure(name) { return function () { return

    name; }; } var description1 = makeClosure("Cloe the Closure"); var description2 = makeClosure("Albert the Awesome"); console.log(description1()); console.log(description2());
  34. Shared Functions var Lane = { name: "Lane the Lambda",

    description: function () { return this.name; } }; var description = Lane.description; var Fred = { description: Lane.description, name: "Fred the Functor" }; // Call the function from four different scopes console.log(Lane.description()); console.log(Fred.description()); console.log(description()); console.log(description.call({ name: "Zed the Zetabyte" }));
  35. Classical Constructors function Rectangle(width, height) { this.width = width; this.height

    = height; } Rectangle.prototype.getArea = function () { return this.width * this.height; }; Rectangle.prototype.getPerimeter = function () { return 2 * (this.width + this.height); };
  36. Classical Constructors function Square(side) { this.width = side; this.height =

    side; } // Make Square inherit from Rectangle Square.prototype.__proto__ = Rectangle.prototype; // Override a method Square.prototype.getPerimeter = function () { return this.width * 4; };
  37. Classical Constructors // Add a nice toString method to the

    parent class Rectangle.prototype.toString = function toString() { return this.constructor.name + " a=" + this.getArea() + " p=" + this.getPerimeter(); }; var rect = new Rectangle(6, 4); var sqr = new Square(5); console.log(rect.toString()) console.log(sqr.toString())
  38. Pure Prototypal Objects var Rectangle = { name: "Rectangle", getArea:

    function getArea() { return this.width * this.height; }, getPerimeter: function getPerimeter() { return 2 * (this.width + this.height); }, toString: function toString() { return this.name + " a=" + this.getArea() + " p=" + this.getPerimeter(); } };
  39. Pure Prototypal Objects var Square = Object.create(Rectangle); Square.name = "Square";

    Square.getArea = function getArea() { return this.width * this.width; }; Square.getPerimeter = function getPerimeter() { return this.width * 4; };
  40. Pure Prototypal Objects var rect = Object.create(Rectangle); rect.width = 6;

    rect.height = 4; var square = Object.create(Square); square.width = 5; console.log(rect.toString()); console.log(square.toString());
  41. Object Factories function Controller(model, view) { view.update(model.value); return { up:

    function onUp(evt) { model.value++; view.update(model.value); }, down: function onDown(evt) { model.value--; view.update(model.value); }, save: function onSave(evt) { model.save(); view.close(); } }; }
  42. Object Factories var on = Controller( { // Inline a

    mock model value: 5, save: function save() { console.log("Saving value " + this.value); } }, { // Inline a mock view update: function update(newValue) { console.log("View now has " + newValue); }, close: function close() { console.log("Now hiding view"); } } ); setTimeout(on.up, 100); setTimeout(on.down, 200); setTimeout(on.save, 300);
  43. Object Factories // Output View now has 5 View now

    has 6 View now has 5 Saving value 5 Now hiding view