SlideShare ist ein Scribd-Unternehmen logo
1 von 154
Downloaden Sie, um offline zu lesen
Monday, March 11, 13
WER BIN ICH?


    • Sebastian        Springer

    • https://github.com/sspringer82

    • @basti_springer

    • Teamlead         @ Mayflower



Monday, March 11, 13
THEMEN
    • Installation                • Dateisystem

    • Node.js          Shell      • Debugger

    • Kernkomponenten             • Child_Process

    • NPM                         • Cluster

    • Events                      • Tests

    • Streams                     • Promises

    • HTTP

Monday, March 11, 13
https://github.com/sspringer82/
                            nodeworkshop




Monday, March 11, 13
INSTALLATION




Monday, March 11, 13
HTTP://NODEJS.ORG/
                         DOWNLOAD/



Monday, March 11, 13
INSTALLATION




Monday, March 11, 13
INSTALLATION
                       Auf welchen Systemen ist Node.js verfügbar?




Monday, March 11, 13
INSTALLATION
• Unix                              • Windows

    • /usr/local/bin/node            • C:Program   Filesnodejs
                                      node.exe

    • /usr/local/bin/npm             • C:Program   Filesnodejs
                                      npm

    • /usr/local/lib/node_modules    • C:Program
                                               Filesnodejs
                                      node_modules


Monday, March 11, 13
INSTALLATION

             $ wget http://nodejs.org/dist/v0.8.21/node-v0.8.21.tar.gz
             ...
             $ tar xvzf node-v0.8.21.tar.gz
             ...
             $ cd node-v0.8.21/
             $ ./configure --prefix=/opt/node/node-v0.8.21
             ...
             $ make
             ...
             $ sudo make install
             ...



                               Suchpfad anpassen!

Monday, March 11, 13
INSTALLATION

                        Hat es funktioniert?


                        $ node --version
                        v0.8.22




Monday, March 11, 13
REPL




Monday, March 11, 13
WHAT?




Monday, March 11, 13
READ-EVAL-PRINT-LOOP

                       DIE NODE.JS SHELL



Monday, March 11, 13
REPL

                       $ node
                       > for (var i = 0; i < 3; i++) {
                       ... console.log(i);
                       ... }
                       0
                       1
                       2
                       undefined
                       >




Monday, March 11, 13
REPL
                  .break       Bricht ein Multiline Statement ab

                   .clear      Zurücksetzen + .break (CTRL + C)

                       .exit   Beendet die aktuelle Shell (CTRL + D)

                       .help   Liste der Befehle

                       .save   Speichert die aktuelle Session

                       .load   Lädt eine gespeicherte Session


Monday, March 11, 13
KERNKOMPONENTEN




Monday, March 11, 13
KERNKOMPONENTEN
                              Standard Library


                              Node Bindings


                         V8                      libuv

                                       Eventloop async I/O


Monday, March 11, 13
KERNKOMPONENTEN
                              Standard Library


                              Node Bindings


                         V8                      libuv

                                       Eventloop async I/O


Monday, March 11, 13
KERNKOMPONENTEN




Monday, March 11, 13
KERNKOMPONENTEN
                              Standard Library


                              Node Bindings


                         V8                      libuv

                                       Eventloop async I/O


Monday, March 11, 13
KERNKOMPONENTEN
                              Standard Library


                              Node Bindings


                         V8                      libuv

                                       Eventloop async I/O


Monday, March 11, 13
V8


    • Schneller        Zugriff auf Eigenschaften

    • Dynamische          Erstellung von Maschinencode

    • Garbage          Collection




Monday, March 11, 13
V8 - FAST PROPERTY ACCESS




Monday, March 11, 13
V8 - FAST PROPERTY ACCESS




Monday, March 11, 13
V8 - FAST PROPERTY ACCESS




Monday, March 11, 13
MASCHINENCODE




Monday, March 11, 13
V8 - GARBAGE COLLECTION


    • Programmausführung          wird angehalten

    • Es       wird nur ein Teil des Object Heaps geprüft

    • V8        kennt alle Objekte und Pointer im Speicher




Monday, March 11, 13
KERNKOMPONENTEN
                              Standard Library


                              Node Bindings


                         V8                       libuv

                                       Eventloop async I/O

                                 libev + libeio      IOCP
Monday, March 11, 13
ASYNCHRONE
                         OPERATIONEN
                       node.js   Betriebssystem




                                            Operation
                                            (z.B. lesen)




Monday, March 11, 13
APPLIKATIONEN IN NODE.JS




Monday, March 11, 13
APPLIKATIONEN IN NODE.JS


                       $ node helloWorld.js




Monday, March 11, 13
X                                        X                                        X
                         X                                      X                                      X
                           X                                    X                                    X
                             X                                  X                                  X
                               X                                X                                X
                                 X                              X                              X
                                   X                            X                            X
                                     X                          X                          X
                                       X                        X                        X
                                         X                      X                      X
                                           X                    X                    X
                                             X                  X                  X
                                               X                X                X
                                                 X              X              X
                                                   X            X            X
                                                     X          X          X
                                                       X        X        X
                                                         X      X      X
                                                           X    X    X
                                                             X X X
                       XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                                                             X X X
                                                           X    X    X
                                                         X      X      X
                                                       X        X        X
                                                     X          X          X
                                                   X            X            X
                                                 X              X              X
                                               X                X                X
                                             X                  X                  X
                                           X                    X                    X
                                         X                      X                      X
                                       X                        X                        X
                                     X                          X                          X
                                   X                            X                            X
                                 X                              X                              X
                               X                                X                                X
                             X                                  X                                  X
                           X                                    X                                    X
                         X                                      X                                      X
                       X                                        X                                        X




Monday, March 11, 13
APPLIKATIONEN IN NODE.JS
                       var Star = function () {
                           this.name = 'X',
                           this.height = 20,
                           this.step = 2;
                       };

                       Star.prototype.top = function() {
                           ...
                       };

                       Star.prototype.print = function () {
                           console.log(this.top().join('n'));
                           console.log(this.middle());
                           console.log(this.bottom().join('n'));
                       }

                       ...

                       var star = new Star();
                       star.print();
Monday, March 11, 13
DAS MODULSYSTEM




Monday, March 11, 13
DAS MODULSYSTEM

                           interne Module

                           eigene Module

                               NPM




Monday, March 11, 13
INTERNE MODULE
        Assertion Testing     HTTP        String Decoder
             Buffer          HTTPS             Timers
         Child_Process         Net            TLS/SSL
             Cluster            Os              TTY
             Crypto            Path             UDP
           Debugger          Process            URL
              DNS           QueryString        Utilities
            Domain           Readline            VM
              Event           REPL              ZLIB
          File System        Stream

Monday, March 11, 13
INTERNE MODULE
                       STABILITÄTSINDEX
        Index            Name             Beispiel
               0       Deprecated         util.pump
               1       Experimental    Domain, Cluster
               2         Unstable      Readline, Stream
               3          Stable      HTTP, Query String
               4        API Frozen        OS, Events
               5         Locked           Util, Assert


Monday, March 11, 13
VERWENDUNG INTERNER
                    MODULE
                                intModule.js
                       var os = require('os');

                       console.log('Betriebssystem: ' +
                           os.type() + ' ' +
                           os.platform() + ' ' +
                           os.release() + ' ' +
                           os.arch());




Monday, March 11, 13
INTERNE MODULE - GLOBALS

    • console

    • process

    • require

    • Buffer

    • set/clear-Timeout/Interval

    • __filename        + __dirname

Monday, March 11, 13
EIGENE MODULE




Monday, March 11, 13
EIGENE MODULE

    • OH: “Wenn     ich mir das Zeug, das in Node programmiert
        wurde, so ansehe, sieht das aus wie PHP3. Einfach von oben
        nach unten, alles in einer Datei”

    • Liegen           in einer separaten Datei

    • Exportieren           Klassen, Objekte oder Funktionen

    • Können            an anderer Stelle eingebunden werden


Monday, March 11, 13
EIGENE MODULE
                                 validator.js

    exports.email = function (email) {
        var regex = /^([a-z0-9_.-]+)@([da-z.-]+).([a-z.]{2,6})$/,
            result = regex.exec(email);

              if (result) {
                  return true;
              }

              return false;
    };




Monday, March 11, 13
EIGENE MODULE
                                   validator.js

      exports.email = function (email) {
          var regex = /^([a-z0-9_.-]+)@([da-z.-]+).([a-z.]{2,6})$/,
              result = regex.exec(email);

                if (result) {
                    return true;
                }

                return false;
      };




Monday, March 11, 13
VERWENDUNG EIGENER
                       MODULE
                                modules.js

      var validator = require('./validator.js'),
          mail = ['sebastian.springer@mayflower.de', 'Invalid Address'];

      for (var i = 0; i < mail.length; i++) {
          if (validator.email(mail[i])) {
              console.log((i + 1) + '. Mailadresse ist gültig');
          } else {
              console.log((i + 1) + '. Mailadresse ist ungültig');
          }
      }




Monday, March 11, 13
VERWENDUNG EIGENER
                       MODULE
                                modules.js

      var validator = require('./validator.js'),
          mail = ['sebastian.springer@mayflower.de', 'Invalid Address'];

      for (var i = 0; i < mail.length; i++) {
          if (validator.email(mail[i])) {
              console.log((i + 1) + '. Mailadresse ist gültig');
          } else {
              console.log((i + 1) + '. Mailadresse ist ungültig');
          }
      }




Monday, March 11, 13
EIGENE MODULE


                       $ node modules.js
                       1. Mailadresse ist gültig
                       2. Mailadresse ist ungültig




Monday, March 11, 13
Monday, March 11, 13
NPM


    • Node             Package Manager (von Isaac Schlueter)

    • Bestandteil          von Node.js seit 0.6.3

    • https://github.com/isaacs/npm




Monday, March 11, 13
NPM - REPO


    • Hier             kommen die Pakete für das npm-Kommando her

    • https://npmjs.org/

    • Aktuell            über 24.000 Pakete

    • https://registry.npmjs.org/-/all/




Monday, March 11, 13
KOMMANDOS

    • npm              search <package>

    • npm              install <package>

    • npm              list

    • npm              update

    • npm              remove


Monday, March 11, 13
NPM SEARCH
$ npm se mysql
npm http GET https://registry.npmjs.org/-/all/since?stale=update_aft...
npm http 200 https://registry.npmjs.org/-/all/since?stale=update_aft...
NAME           DESCRIPTION                 AUTHOR DATE       KEYWORDS...
Accessor_M... A MySQL database wrapper... =bu      2012-1... mysql ac...
any-db         Database-agnostic connec... =grncdr 2013-0... mysql po...
autodafe       mvc framework for node w... =jifeon 2012-1... mvc fram...
backbone-m... A sync module for Backbo... =ccowan 2012-1...
caminte        ORM for every database: ... =biggor 2013-0... caminte ...
connect-my... a MySQL session store fo... =nathan 2012-0...
connect-my... A MySQL session store fo... =daniel 2011-0...
cormo          ORM framework for Node.j... =croqui 2013-0... orm mong...




Monday, March 11, 13
NPM INSTALL
         $ npm in mysql
         npm http GET https://registry.npmjs.org/mysql
         npm http 200 https://registry.npmjs.org/mysql
         npm http GET https://registry.npmjs.org/bignumber.js/1.0.1
         npm http GET https://registry.npmjs.org/require-all/0.0.3
         npm http 200 https://registry.npmjs.org/require-all/0.0.3
         npm http GET https://registry.npmjs.org/require-all/-/requi...
         npm http 200 https://registry.npmjs.org/bignumber.js/1.0.1
         npm http GET https://registry.npmjs.org/bignumber.js/-/bign...
         npm http 200 https://registry.npmjs.org/require-all/-/requi...
         npm http 200 https://registry.npmjs.org/bignumber.js/-/bign...
         mysql@2.0.0-alpha7 node_modules/mysql
         !"" require-all@0.0.3
         #"" bignumber.js@1.0.1




Monday, March 11, 13
NPM LIST


                       $ npm ls
                       /srv/node
                       #"$ mysql@2.0.0-alpha7
                         !"" bignumber.js@1.0.1
                         #"" require-all@0.0.3




Monday, March 11, 13
NPM UPDATE

              $ npm up
              npm http   GET   https://registry.npmjs.org/mysql
              npm http   304   https://registry.npmjs.org/mysql
              npm http   GET   https://registry.npmjs.org/require-all/0.0.3
              npm http   GET   https://registry.npmjs.org/bignumber.js/1.0.1
              npm http   304   https://registry.npmjs.org/bignumber.js/1.0.1
              npm http   304   https://registry.npmjs.org/require-all/0.0.3




Monday, March 11, 13
NPM REMOVE


                       $ npm rm mysql
                       $ npm ls
                       /srv/node
                       #"" (empty)




Monday, March 11, 13
EIGENE NPM-PAKETE




Monday, March 11, 13
{
                           "author": {
                              "name": "Felix Geisendörfer",
                              "email": "felix@debuggable.com",
                              "url": "http://debuggable.com/"
                           },
                           "name": "mysql",
                           "description": "A node.js driver for mysql...",
                           "version": "2.0.0-alpha7",
                           "repository": {
                              "url": ""
                           },
                           "main": "./index",
                           "scripts": {
                              "test": "make test"
                           },
                           "engines": {
                              "node": "*"
                           },
                           "dependencies": {
                              "require-all": "0.0.3",
                              "bignumber.js": "1.0.1"
                           },
                           "devDependencies": {
                              "utest": "0.0.6",
                              "urun": "0.0.6",
                              "underscore": "1.3.1"
                           },
                           "optionalDependencies": {},
                           "readme": "# node-mysqlnn[![Build Status]...",
                           "readmeFilename": "Readme.md",
                           "_id": "mysql@2.0.0-alpha7",
Monday, March 11, 13       "_from": "mysql"
EIGENE NPM-PAKETE


    • npm              adduser

         • Username, Passwort, E-Mail

    • npm              publish <folder>|<tarball>




Monday, March 11, 13
https://github.com/joyent/node/wiki/
                        Modules




Monday, March 11, 13
EVENTS




Monday, March 11, 13
EVENTS
                       Event Emitter                         Subscriber


                               on(‘message’, function (e) {...


                                   emit(‘message’, ‘data’)




Monday, March 11, 13
EVENTS

    • Basis            vieler Module

    • Grundlage             für eventgetriebene Architektur

    • Ereignisse           zum Informationsaustausch

    • emit(event, [arg1], [arg2], [...])         - Publish

    • on(event, listener)          - Subscribe


Monday, March 11, 13
EVENTEMITTER
                                         messageBus.js

                       var EventEmitter = require('events').EventEmitter,
                           util = require('util');

                       var MessageBus = function () {};

                       util.inherits(MessageBus, EventEmitter);

                       exports.MessageBus = MessageBus;




Monday, March 11, 13
EVENTEMITTER
                                        events.js

                  var MessageBus = require('./messageBus.js').MessageBus;

                  var mb = new MessageBus();

                  mb.on('message', function (data) {
                      console.log('Received new message: ' + data)
                  });

                  mb.emit('message', 'Hello World');




Monday, March 11, 13
EVENTEMITTER


                       $ node events.js
                       Received new message: Hello World




Monday, March 11, 13
EVENTS



    • Wo           kommen Events zum Einsatz?

         • child_process, cluster, dgram, domain, fs, http, net, readline,
             repl, stream, tls




Monday, March 11, 13
STREAMS




Monday, March 11, 13
STREAMS


    • Repräsentieren             Datenströme in Node.js

    • Abstraktes             Interface

    • Les-             und/oder schreibbare Streams




Monday, March 11, 13
READABLE STREAM

    • Events                   • Methoden

         • data                 • pause

         • end                  • resume

         • error                • destroy

         • close                • pipe

                                • setEncoding

Monday, March 11, 13
WRITABLE STREAM

    • Events                   • Methoden

         • drain                • write

         • error                • end

         • close                • destroy

         • pipe                 • destroySoon




Monday, March 11, 13
STREAMS



    • Wo           kommen Streams zum Einsatz?

         • fs, http, net   repl, tls, zlib




Monday, March 11, 13
STREAMS IN DER PRAXIS?




Monday, March 11, 13
http://www.google.com




Monday, March 11, 13
DER KLASSIKER




Monday, March 11, 13
HTTP-SERVER
                                       http.js

                       var http = require('http');

                       http.createServer(function (req, res) {
                           res.end('Hello World');
                       }).listen(8080);




Monday, March 11, 13
HTTP-SERVER
                         $ node http.js




Monday, March 11, 13
require('http').createServer(function (req, res) {
                   var body, status, reqData;

                       if (req.headers['user-agent'].search(/MSIE/) != -1) {
                           body = 'wrong Browser';
                           status = 403;
                       } else {
                           body = 'Hello Client';
                           status = 200;
                       }

                       req.on('data', function (data) {
                           reqData += data;
                       }).on('end', function () {
                           if (reqData) console.log(reqData);
                       });

                   res.writeHead(status, {
                       'Content-Length': body.length,
                       'Content-Type': 'text/plain' });
                   res.write(body);
                   res.end();
               }).listen(8080);


Monday, March 11, 13
HTTP-SERVER



    • http.ServerRequest: Readable   Stream

    • http.ServerResponse: Writable   Stream




Monday, March 11, 13
HTTP-CLIENT?




Monday, March 11, 13
var options = {
                  hostname: 'www.google.de',
                  port: 80,
                  path: '/',
                  method: 'get'
              };

              var req = require('http').request(options, function(res) {
                  console.log(res);
                  res.setEncoding('utf8');
                  res.on('data', function (chunk) {
                      console.log('BODY: ' + chunk);
                  });
              });

              req.on('error', function(e) {
                  console.log('problem with request: ' + e.message);
              });

              req.write('datan');
              req.end();



Monday, March 11, 13
var options = {
                  hostname: 'www.google.de',
                  port: 80,
                  path: '/',
                  method: 'get'
              };

              var req = require('http').request(options, function(res) {
                  console.log(res);
                  res.setEncoding('utf8');
                  res.on('data', function (chunk) {
                      console.log('BODY: ' + chunk);
                  });
              });

              req.write('datan');
              req.end();




Monday, March 11, 13
DATEISYSTEM




Monday, March 11, 13
DATEISYSTEM-FUNKTIONEN

    • exists           • unlink

    • readFile         • chmod

    • writeFile        • chown

    • appendFile       • ...

    • watchFile

    • rename

Monday, March 11, 13
SYNC VS. ASYNC




Monday, March 11, 13
DATEI LESEN

                       var fs = require('fs')
                           filename = process.argv[2] || 'input.txt';

                       fs.readFile(filename, 'utf8', function (err, data) {
                           if (err) {
                               console.error("File cound not be opened");
                               return false;
                           }
                           console.log(data);
                           return true;
                       });




Monday, March 11, 13
DATEI LESEN

                       $ node readFile.js
                       Hello World!




Monday, March 11, 13
DATEI LESEN

                              $ node readFile.js
                              Hello World!




                       $ node readFile.js nonexistant.txt
                       File cound not be opened




Monday, March 11, 13
FILE EXISTS
               $ ls -l input.txt
               -rw-r--r-- 1 sspringer   staff   12 Mar   7 09:06 input.txt




Monday, March 11, 13
FILE EXISTS
               $ ls -l input.txt
               -rw-r--r-- 1 sspringer     staff   12 Mar   7 09:06 input.txt


                       var fs = require('fs'),
                           filename = process.argv[2] || 'input.txt';

                       fs.exists(filename, function (exists) {
                           if (exists) {
                               console.log('File exists');
                               return true;
                           }
                           console.error('There is no such file');
                           return false;
                       });




Monday, March 11, 13
FILE EXISTS
               $ ls -l input.txt
               -rw-r--r-- 1 sspringer     staff   12 Mar   7 09:06 input.txt


                       var fs = require('fs'),
                           filename = process.argv[2] || 'input.txt';

                       fs.exists(filename, function (exists) {
                           if (exists) {
                               console.log('File exists');
                               return true;
                           }
                           console.error('There is no such file');
                           return false;
                       });



                                   $ node fileExists.js
                                   File exists

Monday, March 11, 13
APPEND FILE
                         $ cat input.txt
                         Hello World!




Monday, March 11, 13
APPEND FILE
                                        $ cat input.txt
                                        Hello World!

                       var fs = require('fs'),
                           data = process.argv[2] || 'Hello my World';

                       fs.appendFile('input.txt', data, function (err) {
                           if (err) {
                               console.error('Could not write into file');
                               return false;
                           }
                           console.log('Success!');
                           return true;
                       });




Monday, March 11, 13
APPEND FILE
                                        $ cat input.txt
                                        Hello World!

                       var fs = require('fs'),
                           data = process.argv[2] || 'Hello my World';

                       fs.appendFile('input.txt', data, function (err) {
                           if (err) {
                               console.error('Could not write into file');
                               return false;
                           }
                           console.log('Success!');
                           return true;
                       });

                              $ node appendFile.js 'Hallo München!'
                              Success!
                              $ cat input.txt
                              Hello World!Hallo München!
Monday, March 11, 13
WATCH FILE
                       var fs = require('fs');

                       fs.watch('input.txt', function (e) {
                           if (e === 'change') {
                               console.log('File changed');
                           } else if (e === 'rename') {
                               console.log('File renamed');
                           }
                       });




Monday, March 11, 13
WATCH FILE
                       var fs = require('fs');

                       fs.watch('input.txt', function (e) {
                           if (e === 'change') {
                               console.log('File changed');
                           } else if (e === 'rename') {
                               console.log('File renamed');
                           }
                       });


                               $ node watchFile.js




Monday, March 11, 13
WATCH FILE
                       var fs = require('fs');

                       fs.watch('input.txt', function (e) {
                           if (e === 'change') {
                               console.log('File changed');
                           } else if (e === 'rename') {
                               console.log('File renamed');
                           }
                       });


                               $ node watchFile.js


                          $ echo 'Hello World!' > input.txt




Monday, March 11, 13
WATCH FILE
                       var fs = require('fs');

                       fs.watch('input.txt', function (e) {
                           if (e === 'change') {
                               console.log('File changed');
                           } else if (e === 'rename') {
                               console.log('File renamed');
                           }
                       });


                               $ node watchFile.js


                          $ echo 'Hello World!' > input.txt


                              $ node watchFile.js
                              File changed

Monday, March 11, 13
DEBUGGER




Monday, March 11, 13
BEISPIELCODE
                       var myObj = {a: 1, b: 2};

                       console.log(myObj);

                       myObj.a = 'Hello';

                       console.log(myObj);

                       for (var i = 0; i < 10; i++) {
                           var helper = function () {
                               // do something
                               console.log(i)
                           };
                           helper();
                       }



Monday, March 11, 13
DEBUGGER

                       $ node debug debugger.js
                       < debugger listening on port 5858
                       connecting... ok
                       break in debugger.js:1
                         1 var myObj = {a: 1, b: 2};
                         2
                         3 console.log(myObj);
                       debug>




Monday, March 11, 13
DEBUGGER

                       $ node debug debugger.js
                       < debugger listening on port 5858
                       connecting... ok
                       break in debugger.js:1
                         1 var myObj = {a: 1, b: 2};
                         2
                         3 console.log(myObj);
                       debug>




Monday, March 11, 13
DEBUGGER - STEP

                       Kommando   Bedeutung   Beschreibung

                          n          next       Fortsetzen

                          c          cont       Step over

                          s          step        Step in

                          o          out         Step out


Monday, March 11, 13
DEBUGGER - WATCH


    • watch(expression)

    • unwatch(expression)

    • watchers




Monday, March 11, 13
DEBUGGER - WATCH

                         debug> watch('myObj')
                         debug> n
                         break in debugger.js:3
                         Watchers:
                           0: myObj = {"b":2,"a":1}

                           1 var myObj = {a: 1, b: 2};
                           2
                           3 console.log(myObj);
                           4
                           5 myObj.a = 'Hello';
                         debug>




Monday, March 11, 13
DEBUGGER - WATCH

                         debug> watch('myObj')
                         debug> n
                         break in debugger.js:3
                         Watchers:
                           0: myObj = {"b":2,"a":1}

                           1 var myObj = {a: 1, b: 2};
                           2
                           3 console.log(myObj);
                           4
                           5 myObj.a = 'Hello';
                         debug>




Monday, March 11, 13
DEBUGGER - REPL
                        debug> repl
                        Press Ctrl + C to leave debug repl
                        > myObj
                        { b: 2, a: 1 }
                        > myObj.b = 14;
                        14
                        > myObj
                        { b: 14, a: 1 }
                        debug> n
                        < { a: 1, b: 14 }
                        break in debugger.js:5
                        Watchers:
                           0: myObj = {"b":14,"a":1}

                          3 console.log(myObj);
                          4
                          5 myObj.a = 'Hello';
                          6
                          7 console.log(myObj);
                        debug>
Monday, March 11, 13
DEBUGGER


    • Kommandozeilen         Debugger

    • Kommandos

    • Debugging        einer Applikation




Monday, March 11, 13
CHILD_PROCESS




Monday, March 11, 13
CHILD_PROCESS


    • spawn             - Kommandoausführung

    • exec             - Kommandoausführung in Puffer

    • execFile           - Dateiausführung in Puffer

    • fork         - Node Prozess



Monday, March 11, 13
ETWAS RECHENINTENSIVES
                                           cp1.js
                       module.exports = function () {
                           var i, n = 1, results = 1;
                           primeLoop: while (results < 300000) {
                               n += 1;
                               for (i = 2; i <= Math.sqrt(n); i += 1) {
                                   if (n % i === 0) {
                                       continue primeLoop;
                                   }
                               }
                               results += 1;
                           }
                           return n;
                       };




Monday, March 11, 13
potenziell
                   ETWAS BLOCKIERENDES
                                        cp2.js

                var http = require('http');

                http.createFakeServer(function (req, res) {
                    res.writeHead(200, {'Content-Type': 'text/plain'});
                    res.end('Hello Worldn');
                }).listen(1337, '127.0.0.1');

                console.log('Server running at http://127.0.0.1:1337/');




Monday, March 11, 13
ETWAS BLOCKIERENDES
                                           cp3.js
                var http = require('http'),
                    prime = require('./cp1.js');

                http.createServer(function (req, res) {
                    console.time('Request answered in');
                    console.log('incoming Request');

                       var number = prime();

                       res.writeHead(200, {'Content-Type': 'text/plain'});
                       res.end('Hello Worldn');

                    console.timeEnd('Request answered in');
                }).listen(1337, '127.0.0.1');

                console.log('Server running at http://127.0.0.1:1337/');


Monday, March 11, 13
ETWAS BLOCKIERENDES


                       $ node cp3.js
                       Server running at http://127.0.0.1:1337/
                       incoming Request
                       Request answered in: 4713ms
                       incoming Request
                       Request answered in: 4703ms




Monday, March 11, 13
DIE LÖSUNG: WIR FORKEN




Monday, March 11, 13
CHILD_PROCESS
                                           cp4.js
        var http = require('http');

        http.createServer(function (req, res) {
            console.time('Request answered in');
            console.log('incoming Request');

                  require('child_process').fork('./primeHelper.js')
                  .on('message', function (data) {
                      res.writeHead(200, {'Content-Type': 'text/plain'});
                      res.end('The 300000st prime number is: ' + data.prime);

                       console.timeEnd('Request answered in');
            });
        }).listen(1337, '127.0.0.1');

        console.log('Server running at http://127.0.0.1:1337/');

Monday, March 11, 13
CHILD_PROCESS
                               primeHelper.js


                       var prime = require('./cp1.js')();

                       process.send({'prime': prime});




Monday, March 11, 13
CHILD_PROCESS


                       $ node cp4.js
                       Server running at http://127.0.0.1:1337/
                       incoming Request
                       incoming Request
                       Request answered in: 4242ms
                       Request answered in: 4913ms




Monday, March 11, 13
CHILD_PROCESS


    • Threadmodell     von Node.js

    • Möglichkeiten    von child_process - fork, spawn, exec

    • Kommunikation     zwischen Eltern- und Kindprozess




Monday, March 11, 13
CLUSTER




Monday, March 11, 13
CLUSTER


    • Loadbalancing          über CPU

    • Funktioniert         mit allen Instanzen von “net.Server”

         • ...auch     mit http




Monday, March 11, 13
cluster.js
var cluster = require('cluster'),
    http = require('http'),
    workers = 2;

if (cluster.isMaster) {
    for (var i = 0; i < workers; i++) {
         cluster.fork();
    }
} else {
    console.log('Worker ' + cluster.worker.process.pid + ' started');

          http.createServer(function(req, res) {

        console.log('Worker ' + cluster.worker.process.pid + '
responds');

              res.writeHead(200);
              res.end("hello worldn");
          }).listen(8000);
}




Monday, March 11, 13
clusterClient.js


                   var http = require('http');

                   for (var i = 0; i < 100; i++) {
                       http.get('http://localhost:8000', function (res) {
                           console.log(res);
                       });
                   }




Monday, March 11, 13
CLUSTER



    • node             cluster.js

    • node             clusterClient.js




Monday, March 11, 13
CLUSTER
                       Worker   38128   responds
                       Worker   38128   responds
                       Worker   38127   responds
                       Worker   38127   responds
                       Worker   38128   responds
                       Worker   38127   responds
                       Worker   38128   responds
                       Worker   38127   responds
                       Worker   38127   responds
                       Worker   38127   responds
                       Worker   38128   responds
                       Worker   38127   responds
                       Worker   38128   responds
                       Worker   38127   responds
                       Worker   38128   responds
                       Worker   38127   responds
                       Worker   38127   responds
                       Worker   38128   responds
                       Worker   38127   responds

Monday, March 11, 13
TESTING




Monday, March 11, 13
UNITTESTS

    • Absicherung             von Applikationen

    • Tests            auf Funktionsebene

    • Node.js            testet eigene Module ebenfalls

         • Assert-Modul

         • node-v0.8.22/test/simple



Monday, March 11, 13
ASSERTION TESTING




Monday, March 11, 13
ASSERTION TESTING


    • var        assert = require(‘assert’)

    • Assertion-Methoden

    • Sehr             wenig Rückmeldung

    • Nur          ein Failure



Monday, March 11, 13
ASSERTION TESTING
      fail                                       Wirft einen
                                                 AssertionError
      ok(value, [message])                       Pass, wenn der Wert
                                                 true ist
      equal(actual, expected, [message])         Vergleich mit ==

      deepEqual(actual, expected, [message])     Vergleich über
                                                 Strukturen
      strictEqual(actual, expected, [message])   Vergleich mit ===

      throws(block, [error], [message])          Pass, wenn eine
                                                 Exception geworfen
                                                 wird
                             NOT! - notEqual(...)
Monday, March 11, 13
ASSERTION TESTING
                                       assert.js

               var assert = require('assert'),
                   actual = 'Hello World',
                   expected = 'Hello World';

               assert.equal(actual, expected, 'Strings are not Equal');

               assert.notEqual(actual, expected, 'Strings are Equal');

               assert.fail('FAIL!', 'PASS!', 'This fails!');




Monday, March 11, 13
ASSERTION TESTING
$ node assert.js

assert.js:102
  throw new assert.AssertionError({
        ^
AssertionError: Strings are Equal
    at Object.<anonymous> (/tmp/node/assert.js:7:8)
    at Module._compile (module.js:449:26)
    at Object.Module._extensions..js (module.js:467:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Module.runMain (module.js:492:10)
    at process.startup.processNextTick.process._tickCallback (node.js:
244:9)




Monday, March 11, 13
NODEUNIT




Monday, March 11, 13
NODEUNIT


    • npm              install -g nodeunit

    • Die         gleichen Assertion-Methoden wie im Assert-Modul

    • More             verbose

    • Mehrere              Failures



Monday, March 11, 13
module.exports = {
          setUp: function (callback) {
              console.log('setUp');
              callback();
          },
          tearDown: function (callback) {
              console.log('tearDown');
              callback();
          },
          firstExample: function (test) {
              console.log('firstExample')
              test.equal('Hello', 'Hello', 'Strings are not Equal');
              test.done();
          },
          exampleGroup: {
              secondExample: function (test) {
                  test.notEqual('Hello', 'Hello', 'Strings are Equal');
                  test.done();
              },
              thirdExample: function (test) {
                  test.fail('FAIL!', 'PASS!', 'This fails!');
                  test.done();
              }
          }
      }
Monday, March 11, 13
$ nodeunit nodeunit.js

                       nodeunit.js
                       setUp
                       firstExample
                       tearDown
                       ✔ firstExample
                       setUp
                       tearDown
                       ✖ exampleGroup - secondExample

                       Assertion Message: Strings are Equal
                       AssertionError: 'Hello World' != 'Hello World'
                           at Object.assertWrapper [as notEqual] (...

                       setUp
                       tearDown
                       ✖ exampleGroup - thirdExample

                       AssertionError: 'FAIL!' undefined 'PASS!'
                           at Object.assertWrapper [as fail] (...


                       FAILURES: 2/3 assertions failed (5ms)

Monday, March 11, 13
PROMISES




Monday, March 11, 13
PROMISES

    • Ergebnis         eines asynchronen Funktionsaufrufs

    • Rückgabewert           oder Exception

    • Promise          statt Blocking

    • CommonJS            Proposal

    • Bis       0.2 Bestandteil von Node


Monday, March 11, 13
PYRAMID OF DOOM

                       step1(function (value1) {
                           step2(value1, function (value2) {
                               step3(value2, function (value3) {
                                   step3(value3, function (value4) {
                                       // do something
                                   });
                               });
                           });
                       });




Monday, March 11, 13
PROMISES

                       Q.fcall(step1)
                           .then(step2)
                           .then(step3)
                           .then(step4)
                           .then(function (value4) {
                               // do something with value 4
                           }, function (error) {
                               // Handle any error from step1 through step4
                           })
                           .end();




Monday, March 11, 13
PROMISE-LIBRARIES


    • https://github.com/kriskowal/q

    • https://github.com/kriszyp/node-promise   (lightweight)

    • https://github.com/kriszyp/promised-io   (complete API)

    • ...




Monday, March 11, 13
OHNE PROMISES
 var fs = require('fs');

 fs.exists('input.txt', function (exists) {
     fs.stat('input.txt', function (err, stats) {
         fs.open('input.txt', 'r+', function (err, fd) {
             fs.read(fd, new Buffer(stats.size), 0, stats.size, null,
                 function (err, read, buff) {
                     if (err) throw err;
                     console.log(buff.toString());
                     fs.close(fd, function () {
                         console.log('File Handle closed');
                     });
                 }
             )
         });
     });
 });



Monday, March 11, 13
MIT PROMISES




Monday, March 11, 13
var fs = require('promised-io/fs'), gStat, gFd;

var open = function (stat) {
        gStat = stat;
        return fs.open('input.txt', 'r+');
    },
    read = function (fd) {
        gFd = fd;
        return fs.read(fd, new Buffer(gStat.size), 0, gStat.size, null)
    },
    close = function (args) {
        console.log(args[1].toString());
        return fs.close(gFd);
    },
    catchall = function (err) {
        console.log(err);
    },
    finished = function () {
        console.log('File Handle closed');
    };

fs.stat('input.txt')
    .then(open)
    .then(read)
    .then(close)
    .then(finished, catchall);
Monday, March 11, 13
AUSFÜHRUNG


                       $ node promises2.js
                       Hello World

                       File Handle closed




Monday, March 11, 13
JETZT HABT IHR’S GESCHAFFT




Monday, March 11, 13
FRAGEN?




Monday, March 11, 13
KONTAKT
                       Sebastian Springer
                       sebastian.springer@mayflower.de

                       Mayflower GmbH
                       Mannhardtstr. 6
                       80538 München
                       Deutschland

                       @basti_springer

                       https://github.com/sspringer82



Monday, March 11, 13
OHNE PROMISES




Monday, March 11, 13
OHNE PROMISES




Monday, March 11, 13
PROMISES




Monday, March 11, 13
PROMISES




Monday, March 11, 13
PROMISES




Monday, March 11, 13
PROMISES




Monday, March 11, 13

Weitere ähnliche Inhalte

Ähnlich wie Einführung in Node.js

vbench: lightweight performance testing for Python
vbench: lightweight performance testing for Pythonvbench: lightweight performance testing for Python
vbench: lightweight performance testing for Python
Wes McKinney
 
nginxをソースからインストールしてみたよ
nginxをソースからインストールしてみたよnginxをソースからインストールしてみたよ
nginxをソースからインストールしてみたよ
mamoru tateoka
 
Conquistando el Servidor con Node.JS
Conquistando el Servidor con Node.JSConquistando el Servidor con Node.JS
Conquistando el Servidor con Node.JS
Caridy Patino
 
Torquebox - O melhor dos dois mundos
Torquebox - O melhor dos dois mundosTorquebox - O melhor dos dois mundos
Torquebox - O melhor dos dois mundos
Bruno Oliveira
 
Deploying and maintaining your software with RPM/APT
Deploying and maintaining your software with RPM/APTDeploying and maintaining your software with RPM/APT
Deploying and maintaining your software with RPM/APT
Joshua Thijssen
 
OpenSky Infrastructure
OpenSky InfrastructureOpenSky Infrastructure
OpenSky Infrastructure
Jonathan Wage
 
TorqueBox - When Java meets Ruby
TorqueBox - When Java meets RubyTorqueBox - When Java meets Ruby
TorqueBox - When Java meets Ruby
Bruno Oliveira
 

Ähnlich wie Einführung in Node.js (20)

vbench: lightweight performance testing for Python
vbench: lightweight performance testing for Pythonvbench: lightweight performance testing for Python
vbench: lightweight performance testing for Python
 
Using Java from Ruby with JRuby IRB
Using Java from Ruby with JRuby IRBUsing Java from Ruby with JRuby IRB
Using Java from Ruby with JRuby IRB
 
RunDeck
RunDeckRunDeck
RunDeck
 
eZ Publish nextgen
eZ Publish nextgeneZ Publish nextgen
eZ Publish nextgen
 
nginxをソースからインストールしてみたよ
nginxをソースからインストールしてみたよnginxをソースからインストールしてみたよ
nginxをソースからインストールしてみたよ
 
Caridy patino - node-js
Caridy patino - node-jsCaridy patino - node-js
Caridy patino - node-js
 
Conquistando el Servidor con Node.JS
Conquistando el Servidor con Node.JSConquistando el Servidor con Node.JS
Conquistando el Servidor con Node.JS
 
Introduction to node.js by Ran Mizrahi @ Reversim Summit
Introduction to node.js by Ran Mizrahi @ Reversim SummitIntroduction to node.js by Ran Mizrahi @ Reversim Summit
Introduction to node.js by Ran Mizrahi @ Reversim Summit
 
Torquebox - O melhor dos dois mundos
Torquebox - O melhor dos dois mundosTorquebox - O melhor dos dois mundos
Torquebox - O melhor dos dois mundos
 
Deploying and maintaining your software with RPM/APT
Deploying and maintaining your software with RPM/APTDeploying and maintaining your software with RPM/APT
Deploying and maintaining your software with RPM/APT
 
OpenSky Infrastructure
OpenSky InfrastructureOpenSky Infrastructure
OpenSky Infrastructure
 
Lightweight Virtualization: LXC containers & AUFS
Lightweight Virtualization: LXC containers & AUFSLightweight Virtualization: LXC containers & AUFS
Lightweight Virtualization: LXC containers & AUFS
 
OSDC 2016 - Interesting things you can do with ZFS by Allan Jude&Benedict Reu...
OSDC 2016 - Interesting things you can do with ZFS by Allan Jude&Benedict Reu...OSDC 2016 - Interesting things you can do with ZFS by Allan Jude&Benedict Reu...
OSDC 2016 - Interesting things you can do with ZFS by Allan Jude&Benedict Reu...
 
Macruby - RubyConf Presentation 2010
Macruby - RubyConf Presentation 2010Macruby - RubyConf Presentation 2010
Macruby - RubyConf Presentation 2010
 
De vuelta al pasado con SQL y stored procedures
De vuelta al pasado con SQL y stored proceduresDe vuelta al pasado con SQL y stored procedures
De vuelta al pasado con SQL y stored procedures
 
Rails Intro & Tutorial
Rails Intro & TutorialRails Intro & Tutorial
Rails Intro & Tutorial
 
TorqueBox - When Java meets Ruby
TorqueBox - When Java meets RubyTorqueBox - When Java meets Ruby
TorqueBox - When Java meets Ruby
 
Mastering ElasticSearch with Ruby and Tire
Mastering ElasticSearch with Ruby and TireMastering ElasticSearch with Ruby and Tire
Mastering ElasticSearch with Ruby and Tire
 
Symfony2 and MongoDB - MidwestPHP 2013
Symfony2 and MongoDB - MidwestPHP 2013   Symfony2 and MongoDB - MidwestPHP 2013
Symfony2 and MongoDB - MidwestPHP 2013
 
DBXTalk: Smalltalk Relational Database Suite
DBXTalk: Smalltalk Relational Database SuiteDBXTalk: Smalltalk Relational Database Suite
DBXTalk: Smalltalk Relational Database Suite
 

Mehr von Sebastian Springer

Mehr von Sebastian Springer (20)

Schnelleinstieg in Angular
Schnelleinstieg in AngularSchnelleinstieg in Angular
Schnelleinstieg in Angular
 
Creating Enterprise Web Applications with Node.js
Creating Enterprise Web Applications with Node.jsCreating Enterprise Web Applications with Node.js
Creating Enterprise Web Applications with Node.js
 
Divide and Conquer – Microservices with Node.js
Divide and Conquer – Microservices with Node.jsDivide and Conquer – Microservices with Node.js
Divide and Conquer – Microservices with Node.js
 
From Zero to Hero – Web Performance
From Zero to Hero – Web PerformanceFrom Zero to Hero – Web Performance
From Zero to Hero – Web Performance
 
Von 0 auf 100 - Performance im Web
Von 0 auf 100 - Performance im WebVon 0 auf 100 - Performance im Web
Von 0 auf 100 - Performance im Web
 
A/B Testing mit Node.js
A/B Testing mit Node.jsA/B Testing mit Node.js
A/B Testing mit Node.js
 
Angular2
Angular2Angular2
Angular2
 
Einführung in React
Einführung in ReactEinführung in React
Einführung in React
 
JavaScript Performance
JavaScript PerformanceJavaScript Performance
JavaScript Performance
 
ECMAScript 6 im Produktivbetrieb
ECMAScript 6 im ProduktivbetriebECMAScript 6 im Produktivbetrieb
ECMAScript 6 im Produktivbetrieb
 
Streams in Node.js
Streams in Node.jsStreams in Node.js
Streams in Node.js
 
JavaScript Performance
JavaScript PerformanceJavaScript Performance
JavaScript Performance
 
Große Applikationen mit AngularJS
Große Applikationen mit AngularJSGroße Applikationen mit AngularJS
Große Applikationen mit AngularJS
 
Testing tools
Testing toolsTesting tools
Testing tools
 
Node.js Security
Node.js SecurityNode.js Security
Node.js Security
 
Typescript
TypescriptTypescript
Typescript
 
Reactive Programming
Reactive ProgrammingReactive Programming
Reactive Programming
 
Best Practices für TDD in JavaScript
Best Practices für TDD in JavaScriptBest Practices für TDD in JavaScript
Best Practices für TDD in JavaScript
 
Warum ECMAScript 6 die Welt ein Stückchen besser macht
Warum ECMAScript 6 die Welt ein Stückchen besser machtWarum ECMAScript 6 die Welt ein Stückchen besser macht
Warum ECMAScript 6 die Welt ein Stückchen besser macht
 
Lean Startup mit JavaScript
Lean Startup mit JavaScriptLean Startup mit JavaScript
Lean Startup mit JavaScript
 

Kürzlich hochgeladen

CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
giselly40
 

Kürzlich hochgeladen (20)

08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your Business
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 

Einführung in Node.js

  • 2. WER BIN ICH? • Sebastian Springer • https://github.com/sspringer82 • @basti_springer • Teamlead @ Mayflower Monday, March 11, 13
  • 3. THEMEN • Installation • Dateisystem • Node.js Shell • Debugger • Kernkomponenten • Child_Process • NPM • Cluster • Events • Tests • Streams • Promises • HTTP Monday, March 11, 13
  • 4. https://github.com/sspringer82/ nodeworkshop Monday, March 11, 13
  • 6. HTTP://NODEJS.ORG/ DOWNLOAD/ Monday, March 11, 13
  • 8. INSTALLATION Auf welchen Systemen ist Node.js verfügbar? Monday, March 11, 13
  • 9. INSTALLATION • Unix • Windows • /usr/local/bin/node • C:Program Filesnodejs node.exe • /usr/local/bin/npm • C:Program Filesnodejs npm • /usr/local/lib/node_modules • C:Program Filesnodejs node_modules Monday, March 11, 13
  • 10. INSTALLATION $ wget http://nodejs.org/dist/v0.8.21/node-v0.8.21.tar.gz ... $ tar xvzf node-v0.8.21.tar.gz ... $ cd node-v0.8.21/ $ ./configure --prefix=/opt/node/node-v0.8.21 ... $ make ... $ sudo make install ... Suchpfad anpassen! Monday, March 11, 13
  • 11. INSTALLATION Hat es funktioniert? $ node --version v0.8.22 Monday, March 11, 13
  • 14. READ-EVAL-PRINT-LOOP DIE NODE.JS SHELL Monday, March 11, 13
  • 15. REPL $ node > for (var i = 0; i < 3; i++) { ... console.log(i); ... } 0 1 2 undefined > Monday, March 11, 13
  • 16. REPL .break Bricht ein Multiline Statement ab .clear Zurücksetzen + .break (CTRL + C) .exit Beendet die aktuelle Shell (CTRL + D) .help Liste der Befehle .save Speichert die aktuelle Session .load Lädt eine gespeicherte Session Monday, March 11, 13
  • 18. KERNKOMPONENTEN Standard Library Node Bindings V8 libuv Eventloop async I/O Monday, March 11, 13
  • 19. KERNKOMPONENTEN Standard Library Node Bindings V8 libuv Eventloop async I/O Monday, March 11, 13
  • 21. KERNKOMPONENTEN Standard Library Node Bindings V8 libuv Eventloop async I/O Monday, March 11, 13
  • 22. KERNKOMPONENTEN Standard Library Node Bindings V8 libuv Eventloop async I/O Monday, March 11, 13
  • 23. V8 • Schneller Zugriff auf Eigenschaften • Dynamische Erstellung von Maschinencode • Garbage Collection Monday, March 11, 13
  • 24. V8 - FAST PROPERTY ACCESS Monday, March 11, 13
  • 25. V8 - FAST PROPERTY ACCESS Monday, March 11, 13
  • 26. V8 - FAST PROPERTY ACCESS Monday, March 11, 13
  • 28. V8 - GARBAGE COLLECTION • Programmausführung wird angehalten • Es wird nur ein Teil des Object Heaps geprüft • V8 kennt alle Objekte und Pointer im Speicher Monday, March 11, 13
  • 29. KERNKOMPONENTEN Standard Library Node Bindings V8 libuv Eventloop async I/O libev + libeio IOCP Monday, March 11, 13
  • 30. ASYNCHRONE OPERATIONEN node.js Betriebssystem Operation (z.B. lesen) Monday, March 11, 13
  • 32. APPLIKATIONEN IN NODE.JS $ node helloWorld.js Monday, March 11, 13
  • 33. X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X Monday, March 11, 13
  • 34. APPLIKATIONEN IN NODE.JS var Star = function () { this.name = 'X', this.height = 20, this.step = 2; }; Star.prototype.top = function() { ... }; Star.prototype.print = function () { console.log(this.top().join('n')); console.log(this.middle()); console.log(this.bottom().join('n')); } ... var star = new Star(); star.print(); Monday, March 11, 13
  • 36. DAS MODULSYSTEM interne Module eigene Module NPM Monday, March 11, 13
  • 37. INTERNE MODULE Assertion Testing HTTP String Decoder Buffer HTTPS Timers Child_Process Net TLS/SSL Cluster Os TTY Crypto Path UDP Debugger Process URL DNS QueryString Utilities Domain Readline VM Event REPL ZLIB File System Stream Monday, March 11, 13
  • 38. INTERNE MODULE STABILITÄTSINDEX Index Name Beispiel 0 Deprecated util.pump 1 Experimental Domain, Cluster 2 Unstable Readline, Stream 3 Stable HTTP, Query String 4 API Frozen OS, Events 5 Locked Util, Assert Monday, March 11, 13
  • 39. VERWENDUNG INTERNER MODULE intModule.js var os = require('os'); console.log('Betriebssystem: ' + os.type() + ' ' + os.platform() + ' ' + os.release() + ' ' + os.arch()); Monday, March 11, 13
  • 40. INTERNE MODULE - GLOBALS • console • process • require • Buffer • set/clear-Timeout/Interval • __filename + __dirname Monday, March 11, 13
  • 42. EIGENE MODULE • OH: “Wenn ich mir das Zeug, das in Node programmiert wurde, so ansehe, sieht das aus wie PHP3. Einfach von oben nach unten, alles in einer Datei” • Liegen in einer separaten Datei • Exportieren Klassen, Objekte oder Funktionen • Können an anderer Stelle eingebunden werden Monday, March 11, 13
  • 43. EIGENE MODULE validator.js exports.email = function (email) { var regex = /^([a-z0-9_.-]+)@([da-z.-]+).([a-z.]{2,6})$/, result = regex.exec(email); if (result) { return true; } return false; }; Monday, March 11, 13
  • 44. EIGENE MODULE validator.js exports.email = function (email) { var regex = /^([a-z0-9_.-]+)@([da-z.-]+).([a-z.]{2,6})$/, result = regex.exec(email); if (result) { return true; } return false; }; Monday, March 11, 13
  • 45. VERWENDUNG EIGENER MODULE modules.js var validator = require('./validator.js'), mail = ['sebastian.springer@mayflower.de', 'Invalid Address']; for (var i = 0; i < mail.length; i++) { if (validator.email(mail[i])) { console.log((i + 1) + '. Mailadresse ist gültig'); } else { console.log((i + 1) + '. Mailadresse ist ungültig'); } } Monday, March 11, 13
  • 46. VERWENDUNG EIGENER MODULE modules.js var validator = require('./validator.js'), mail = ['sebastian.springer@mayflower.de', 'Invalid Address']; for (var i = 0; i < mail.length; i++) { if (validator.email(mail[i])) { console.log((i + 1) + '. Mailadresse ist gültig'); } else { console.log((i + 1) + '. Mailadresse ist ungültig'); } } Monday, March 11, 13
  • 47. EIGENE MODULE $ node modules.js 1. Mailadresse ist gültig 2. Mailadresse ist ungültig Monday, March 11, 13
  • 49. NPM • Node Package Manager (von Isaac Schlueter) • Bestandteil von Node.js seit 0.6.3 • https://github.com/isaacs/npm Monday, March 11, 13
  • 50. NPM - REPO • Hier kommen die Pakete für das npm-Kommando her • https://npmjs.org/ • Aktuell über 24.000 Pakete • https://registry.npmjs.org/-/all/ Monday, March 11, 13
  • 51. KOMMANDOS • npm search <package> • npm install <package> • npm list • npm update • npm remove Monday, March 11, 13
  • 52. NPM SEARCH $ npm se mysql npm http GET https://registry.npmjs.org/-/all/since?stale=update_aft... npm http 200 https://registry.npmjs.org/-/all/since?stale=update_aft... NAME DESCRIPTION AUTHOR DATE KEYWORDS... Accessor_M... A MySQL database wrapper... =bu 2012-1... mysql ac... any-db Database-agnostic connec... =grncdr 2013-0... mysql po... autodafe mvc framework for node w... =jifeon 2012-1... mvc fram... backbone-m... A sync module for Backbo... =ccowan 2012-1... caminte ORM for every database: ... =biggor 2013-0... caminte ... connect-my... a MySQL session store fo... =nathan 2012-0... connect-my... A MySQL session store fo... =daniel 2011-0... cormo ORM framework for Node.j... =croqui 2013-0... orm mong... Monday, March 11, 13
  • 53. NPM INSTALL $ npm in mysql npm http GET https://registry.npmjs.org/mysql npm http 200 https://registry.npmjs.org/mysql npm http GET https://registry.npmjs.org/bignumber.js/1.0.1 npm http GET https://registry.npmjs.org/require-all/0.0.3 npm http 200 https://registry.npmjs.org/require-all/0.0.3 npm http GET https://registry.npmjs.org/require-all/-/requi... npm http 200 https://registry.npmjs.org/bignumber.js/1.0.1 npm http GET https://registry.npmjs.org/bignumber.js/-/bign... npm http 200 https://registry.npmjs.org/require-all/-/requi... npm http 200 https://registry.npmjs.org/bignumber.js/-/bign... mysql@2.0.0-alpha7 node_modules/mysql !"" require-all@0.0.3 #"" bignumber.js@1.0.1 Monday, March 11, 13
  • 54. NPM LIST $ npm ls /srv/node #"$ mysql@2.0.0-alpha7 !"" bignumber.js@1.0.1 #"" require-all@0.0.3 Monday, March 11, 13
  • 55. NPM UPDATE $ npm up npm http GET https://registry.npmjs.org/mysql npm http 304 https://registry.npmjs.org/mysql npm http GET https://registry.npmjs.org/require-all/0.0.3 npm http GET https://registry.npmjs.org/bignumber.js/1.0.1 npm http 304 https://registry.npmjs.org/bignumber.js/1.0.1 npm http 304 https://registry.npmjs.org/require-all/0.0.3 Monday, March 11, 13
  • 56. NPM REMOVE $ npm rm mysql $ npm ls /srv/node #"" (empty) Monday, March 11, 13
  • 58. { "author": { "name": "Felix Geisendörfer", "email": "felix@debuggable.com", "url": "http://debuggable.com/" }, "name": "mysql", "description": "A node.js driver for mysql...", "version": "2.0.0-alpha7", "repository": { "url": "" }, "main": "./index", "scripts": { "test": "make test" }, "engines": { "node": "*" }, "dependencies": { "require-all": "0.0.3", "bignumber.js": "1.0.1" }, "devDependencies": { "utest": "0.0.6", "urun": "0.0.6", "underscore": "1.3.1" }, "optionalDependencies": {}, "readme": "# node-mysqlnn[![Build Status]...", "readmeFilename": "Readme.md", "_id": "mysql@2.0.0-alpha7", Monday, March 11, 13 "_from": "mysql"
  • 59. EIGENE NPM-PAKETE • npm adduser • Username, Passwort, E-Mail • npm publish <folder>|<tarball> Monday, March 11, 13
  • 60. https://github.com/joyent/node/wiki/ Modules Monday, March 11, 13
  • 62. EVENTS Event Emitter Subscriber on(‘message’, function (e) {... emit(‘message’, ‘data’) Monday, March 11, 13
  • 63. EVENTS • Basis vieler Module • Grundlage für eventgetriebene Architektur • Ereignisse zum Informationsaustausch • emit(event, [arg1], [arg2], [...]) - Publish • on(event, listener) - Subscribe Monday, March 11, 13
  • 64. EVENTEMITTER messageBus.js var EventEmitter = require('events').EventEmitter, util = require('util'); var MessageBus = function () {}; util.inherits(MessageBus, EventEmitter); exports.MessageBus = MessageBus; Monday, March 11, 13
  • 65. EVENTEMITTER events.js var MessageBus = require('./messageBus.js').MessageBus; var mb = new MessageBus(); mb.on('message', function (data) { console.log('Received new message: ' + data) }); mb.emit('message', 'Hello World'); Monday, March 11, 13
  • 66. EVENTEMITTER $ node events.js Received new message: Hello World Monday, March 11, 13
  • 67. EVENTS • Wo kommen Events zum Einsatz? • child_process, cluster, dgram, domain, fs, http, net, readline, repl, stream, tls Monday, March 11, 13
  • 69. STREAMS • Repräsentieren Datenströme in Node.js • Abstraktes Interface • Les- und/oder schreibbare Streams Monday, March 11, 13
  • 70. READABLE STREAM • Events • Methoden • data • pause • end • resume • error • destroy • close • pipe • setEncoding Monday, March 11, 13
  • 71. WRITABLE STREAM • Events • Methoden • drain • write • error • end • close • destroy • pipe • destroySoon Monday, March 11, 13
  • 72. STREAMS • Wo kommen Streams zum Einsatz? • fs, http, net repl, tls, zlib Monday, March 11, 13
  • 73. STREAMS IN DER PRAXIS? Monday, March 11, 13
  • 76. HTTP-SERVER http.js var http = require('http'); http.createServer(function (req, res) { res.end('Hello World'); }).listen(8080); Monday, March 11, 13
  • 77. HTTP-SERVER $ node http.js Monday, March 11, 13
  • 78. require('http').createServer(function (req, res) { var body, status, reqData; if (req.headers['user-agent'].search(/MSIE/) != -1) { body = 'wrong Browser'; status = 403; } else { body = 'Hello Client'; status = 200; } req.on('data', function (data) { reqData += data; }).on('end', function () { if (reqData) console.log(reqData); }); res.writeHead(status, { 'Content-Length': body.length, 'Content-Type': 'text/plain' }); res.write(body); res.end(); }).listen(8080); Monday, March 11, 13
  • 79. HTTP-SERVER • http.ServerRequest: Readable Stream • http.ServerResponse: Writable Stream Monday, March 11, 13
  • 81. var options = { hostname: 'www.google.de', port: 80, path: '/', method: 'get' }; var req = require('http').request(options, function(res) { console.log(res); res.setEncoding('utf8'); res.on('data', function (chunk) { console.log('BODY: ' + chunk); }); }); req.on('error', function(e) { console.log('problem with request: ' + e.message); }); req.write('datan'); req.end(); Monday, March 11, 13
  • 82. var options = { hostname: 'www.google.de', port: 80, path: '/', method: 'get' }; var req = require('http').request(options, function(res) { console.log(res); res.setEncoding('utf8'); res.on('data', function (chunk) { console.log('BODY: ' + chunk); }); }); req.write('datan'); req.end(); Monday, March 11, 13
  • 84. DATEISYSTEM-FUNKTIONEN • exists • unlink • readFile • chmod • writeFile • chown • appendFile • ... • watchFile • rename Monday, March 11, 13
  • 85. SYNC VS. ASYNC Monday, March 11, 13
  • 86. DATEI LESEN var fs = require('fs') filename = process.argv[2] || 'input.txt'; fs.readFile(filename, 'utf8', function (err, data) { if (err) { console.error("File cound not be opened"); return false; } console.log(data); return true; }); Monday, March 11, 13
  • 87. DATEI LESEN $ node readFile.js Hello World! Monday, March 11, 13
  • 88. DATEI LESEN $ node readFile.js Hello World! $ node readFile.js nonexistant.txt File cound not be opened Monday, March 11, 13
  • 89. FILE EXISTS $ ls -l input.txt -rw-r--r-- 1 sspringer staff 12 Mar 7 09:06 input.txt Monday, March 11, 13
  • 90. FILE EXISTS $ ls -l input.txt -rw-r--r-- 1 sspringer staff 12 Mar 7 09:06 input.txt var fs = require('fs'), filename = process.argv[2] || 'input.txt'; fs.exists(filename, function (exists) { if (exists) { console.log('File exists'); return true; } console.error('There is no such file'); return false; }); Monday, March 11, 13
  • 91. FILE EXISTS $ ls -l input.txt -rw-r--r-- 1 sspringer staff 12 Mar 7 09:06 input.txt var fs = require('fs'), filename = process.argv[2] || 'input.txt'; fs.exists(filename, function (exists) { if (exists) { console.log('File exists'); return true; } console.error('There is no such file'); return false; }); $ node fileExists.js File exists Monday, March 11, 13
  • 92. APPEND FILE $ cat input.txt Hello World! Monday, March 11, 13
  • 93. APPEND FILE $ cat input.txt Hello World! var fs = require('fs'), data = process.argv[2] || 'Hello my World'; fs.appendFile('input.txt', data, function (err) { if (err) { console.error('Could not write into file'); return false; } console.log('Success!'); return true; }); Monday, March 11, 13
  • 94. APPEND FILE $ cat input.txt Hello World! var fs = require('fs'), data = process.argv[2] || 'Hello my World'; fs.appendFile('input.txt', data, function (err) { if (err) { console.error('Could not write into file'); return false; } console.log('Success!'); return true; }); $ node appendFile.js 'Hallo München!' Success! $ cat input.txt Hello World!Hallo München! Monday, March 11, 13
  • 95. WATCH FILE var fs = require('fs'); fs.watch('input.txt', function (e) { if (e === 'change') { console.log('File changed'); } else if (e === 'rename') { console.log('File renamed'); } }); Monday, March 11, 13
  • 96. WATCH FILE var fs = require('fs'); fs.watch('input.txt', function (e) { if (e === 'change') { console.log('File changed'); } else if (e === 'rename') { console.log('File renamed'); } }); $ node watchFile.js Monday, March 11, 13
  • 97. WATCH FILE var fs = require('fs'); fs.watch('input.txt', function (e) { if (e === 'change') { console.log('File changed'); } else if (e === 'rename') { console.log('File renamed'); } }); $ node watchFile.js $ echo 'Hello World!' > input.txt Monday, March 11, 13
  • 98. WATCH FILE var fs = require('fs'); fs.watch('input.txt', function (e) { if (e === 'change') { console.log('File changed'); } else if (e === 'rename') { console.log('File renamed'); } }); $ node watchFile.js $ echo 'Hello World!' > input.txt $ node watchFile.js File changed Monday, March 11, 13
  • 100. BEISPIELCODE var myObj = {a: 1, b: 2}; console.log(myObj); myObj.a = 'Hello'; console.log(myObj); for (var i = 0; i < 10; i++) { var helper = function () { // do something console.log(i) }; helper(); } Monday, March 11, 13
  • 101. DEBUGGER $ node debug debugger.js < debugger listening on port 5858 connecting... ok break in debugger.js:1 1 var myObj = {a: 1, b: 2}; 2 3 console.log(myObj); debug> Monday, March 11, 13
  • 102. DEBUGGER $ node debug debugger.js < debugger listening on port 5858 connecting... ok break in debugger.js:1 1 var myObj = {a: 1, b: 2}; 2 3 console.log(myObj); debug> Monday, March 11, 13
  • 103. DEBUGGER - STEP Kommando Bedeutung Beschreibung n next Fortsetzen c cont Step over s step Step in o out Step out Monday, March 11, 13
  • 104. DEBUGGER - WATCH • watch(expression) • unwatch(expression) • watchers Monday, March 11, 13
  • 105. DEBUGGER - WATCH debug> watch('myObj') debug> n break in debugger.js:3 Watchers: 0: myObj = {"b":2,"a":1} 1 var myObj = {a: 1, b: 2}; 2 3 console.log(myObj); 4 5 myObj.a = 'Hello'; debug> Monday, March 11, 13
  • 106. DEBUGGER - WATCH debug> watch('myObj') debug> n break in debugger.js:3 Watchers: 0: myObj = {"b":2,"a":1} 1 var myObj = {a: 1, b: 2}; 2 3 console.log(myObj); 4 5 myObj.a = 'Hello'; debug> Monday, March 11, 13
  • 107. DEBUGGER - REPL debug> repl Press Ctrl + C to leave debug repl > myObj { b: 2, a: 1 } > myObj.b = 14; 14 > myObj { b: 14, a: 1 } debug> n < { a: 1, b: 14 } break in debugger.js:5 Watchers: 0: myObj = {"b":14,"a":1} 3 console.log(myObj); 4 5 myObj.a = 'Hello'; 6 7 console.log(myObj); debug> Monday, March 11, 13
  • 108. DEBUGGER • Kommandozeilen Debugger • Kommandos • Debugging einer Applikation Monday, March 11, 13
  • 110. CHILD_PROCESS • spawn - Kommandoausführung • exec - Kommandoausführung in Puffer • execFile - Dateiausführung in Puffer • fork - Node Prozess Monday, March 11, 13
  • 111. ETWAS RECHENINTENSIVES cp1.js module.exports = function () { var i, n = 1, results = 1; primeLoop: while (results < 300000) { n += 1; for (i = 2; i <= Math.sqrt(n); i += 1) { if (n % i === 0) { continue primeLoop; } } results += 1; } return n; }; Monday, March 11, 13
  • 112. potenziell ETWAS BLOCKIERENDES cp2.js var http = require('http'); http.createFakeServer(function (req, res) { res.writeHead(200, {'Content-Type': 'text/plain'}); res.end('Hello Worldn'); }).listen(1337, '127.0.0.1'); console.log('Server running at http://127.0.0.1:1337/'); Monday, March 11, 13
  • 113. ETWAS BLOCKIERENDES cp3.js var http = require('http'), prime = require('./cp1.js'); http.createServer(function (req, res) { console.time('Request answered in'); console.log('incoming Request'); var number = prime(); res.writeHead(200, {'Content-Type': 'text/plain'}); res.end('Hello Worldn'); console.timeEnd('Request answered in'); }).listen(1337, '127.0.0.1'); console.log('Server running at http://127.0.0.1:1337/'); Monday, March 11, 13
  • 114. ETWAS BLOCKIERENDES $ node cp3.js Server running at http://127.0.0.1:1337/ incoming Request Request answered in: 4713ms incoming Request Request answered in: 4703ms Monday, March 11, 13
  • 115. DIE LÖSUNG: WIR FORKEN Monday, March 11, 13
  • 116. CHILD_PROCESS cp4.js var http = require('http'); http.createServer(function (req, res) { console.time('Request answered in'); console.log('incoming Request'); require('child_process').fork('./primeHelper.js') .on('message', function (data) { res.writeHead(200, {'Content-Type': 'text/plain'}); res.end('The 300000st prime number is: ' + data.prime); console.timeEnd('Request answered in'); }); }).listen(1337, '127.0.0.1'); console.log('Server running at http://127.0.0.1:1337/'); Monday, March 11, 13
  • 117. CHILD_PROCESS primeHelper.js var prime = require('./cp1.js')(); process.send({'prime': prime}); Monday, March 11, 13
  • 118. CHILD_PROCESS $ node cp4.js Server running at http://127.0.0.1:1337/ incoming Request incoming Request Request answered in: 4242ms Request answered in: 4913ms Monday, March 11, 13
  • 119. CHILD_PROCESS • Threadmodell von Node.js • Möglichkeiten von child_process - fork, spawn, exec • Kommunikation zwischen Eltern- und Kindprozess Monday, March 11, 13
  • 121. CLUSTER • Loadbalancing über CPU • Funktioniert mit allen Instanzen von “net.Server” • ...auch mit http Monday, March 11, 13
  • 122. cluster.js var cluster = require('cluster'), http = require('http'), workers = 2; if (cluster.isMaster) { for (var i = 0; i < workers; i++) { cluster.fork(); } } else { console.log('Worker ' + cluster.worker.process.pid + ' started'); http.createServer(function(req, res) { console.log('Worker ' + cluster.worker.process.pid + ' responds'); res.writeHead(200); res.end("hello worldn"); }).listen(8000); } Monday, March 11, 13
  • 123. clusterClient.js var http = require('http'); for (var i = 0; i < 100; i++) { http.get('http://localhost:8000', function (res) { console.log(res); }); } Monday, March 11, 13
  • 124. CLUSTER • node cluster.js • node clusterClient.js Monday, March 11, 13
  • 125. CLUSTER Worker 38128 responds Worker 38128 responds Worker 38127 responds Worker 38127 responds Worker 38128 responds Worker 38127 responds Worker 38128 responds Worker 38127 responds Worker 38127 responds Worker 38127 responds Worker 38128 responds Worker 38127 responds Worker 38128 responds Worker 38127 responds Worker 38128 responds Worker 38127 responds Worker 38127 responds Worker 38128 responds Worker 38127 responds Monday, March 11, 13
  • 127. UNITTESTS • Absicherung von Applikationen • Tests auf Funktionsebene • Node.js testet eigene Module ebenfalls • Assert-Modul • node-v0.8.22/test/simple Monday, March 11, 13
  • 129. ASSERTION TESTING • var assert = require(‘assert’) • Assertion-Methoden • Sehr wenig Rückmeldung • Nur ein Failure Monday, March 11, 13
  • 130. ASSERTION TESTING fail Wirft einen AssertionError ok(value, [message]) Pass, wenn der Wert true ist equal(actual, expected, [message]) Vergleich mit == deepEqual(actual, expected, [message]) Vergleich über Strukturen strictEqual(actual, expected, [message]) Vergleich mit === throws(block, [error], [message]) Pass, wenn eine Exception geworfen wird NOT! - notEqual(...) Monday, March 11, 13
  • 131. ASSERTION TESTING assert.js var assert = require('assert'), actual = 'Hello World', expected = 'Hello World'; assert.equal(actual, expected, 'Strings are not Equal'); assert.notEqual(actual, expected, 'Strings are Equal'); assert.fail('FAIL!', 'PASS!', 'This fails!'); Monday, March 11, 13
  • 132. ASSERTION TESTING $ node assert.js assert.js:102 throw new assert.AssertionError({ ^ AssertionError: Strings are Equal at Object.<anonymous> (/tmp/node/assert.js:7:8) at Module._compile (module.js:449:26) at Object.Module._extensions..js (module.js:467:10) at Module.load (module.js:356:32) at Function.Module._load (module.js:312:12) at Module.runMain (module.js:492:10) at process.startup.processNextTick.process._tickCallback (node.js: 244:9) Monday, March 11, 13
  • 134. NODEUNIT • npm install -g nodeunit • Die gleichen Assertion-Methoden wie im Assert-Modul • More verbose • Mehrere Failures Monday, March 11, 13
  • 135. module.exports = { setUp: function (callback) { console.log('setUp'); callback(); }, tearDown: function (callback) { console.log('tearDown'); callback(); }, firstExample: function (test) { console.log('firstExample') test.equal('Hello', 'Hello', 'Strings are not Equal'); test.done(); }, exampleGroup: { secondExample: function (test) { test.notEqual('Hello', 'Hello', 'Strings are Equal'); test.done(); }, thirdExample: function (test) { test.fail('FAIL!', 'PASS!', 'This fails!'); test.done(); } } } Monday, March 11, 13
  • 136. $ nodeunit nodeunit.js nodeunit.js setUp firstExample tearDown ✔ firstExample setUp tearDown ✖ exampleGroup - secondExample Assertion Message: Strings are Equal AssertionError: 'Hello World' != 'Hello World' at Object.assertWrapper [as notEqual] (... setUp tearDown ✖ exampleGroup - thirdExample AssertionError: 'FAIL!' undefined 'PASS!' at Object.assertWrapper [as fail] (... FAILURES: 2/3 assertions failed (5ms) Monday, March 11, 13
  • 138. PROMISES • Ergebnis eines asynchronen Funktionsaufrufs • Rückgabewert oder Exception • Promise statt Blocking • CommonJS Proposal • Bis 0.2 Bestandteil von Node Monday, March 11, 13
  • 139. PYRAMID OF DOOM step1(function (value1) { step2(value1, function (value2) { step3(value2, function (value3) { step3(value3, function (value4) { // do something }); }); }); }); Monday, March 11, 13
  • 140. PROMISES Q.fcall(step1) .then(step2) .then(step3) .then(step4) .then(function (value4) { // do something with value 4 }, function (error) { // Handle any error from step1 through step4 }) .end(); Monday, March 11, 13
  • 141. PROMISE-LIBRARIES • https://github.com/kriskowal/q • https://github.com/kriszyp/node-promise (lightweight) • https://github.com/kriszyp/promised-io (complete API) • ... Monday, March 11, 13
  • 142. OHNE PROMISES var fs = require('fs'); fs.exists('input.txt', function (exists) { fs.stat('input.txt', function (err, stats) { fs.open('input.txt', 'r+', function (err, fd) { fs.read(fd, new Buffer(stats.size), 0, stats.size, null, function (err, read, buff) { if (err) throw err; console.log(buff.toString()); fs.close(fd, function () { console.log('File Handle closed'); }); } ) }); }); }); Monday, March 11, 13
  • 144. var fs = require('promised-io/fs'), gStat, gFd; var open = function (stat) { gStat = stat; return fs.open('input.txt', 'r+'); }, read = function (fd) { gFd = fd; return fs.read(fd, new Buffer(gStat.size), 0, gStat.size, null) }, close = function (args) { console.log(args[1].toString()); return fs.close(gFd); }, catchall = function (err) { console.log(err); }, finished = function () { console.log('File Handle closed'); }; fs.stat('input.txt') .then(open) .then(read) .then(close) .then(finished, catchall); Monday, March 11, 13
  • 145. AUSFÜHRUNG $ node promises2.js Hello World File Handle closed Monday, March 11, 13
  • 146. JETZT HABT IHR’S GESCHAFFT Monday, March 11, 13
  • 148. KONTAKT Sebastian Springer sebastian.springer@mayflower.de Mayflower GmbH Mannhardtstr. 6 80538 München Deutschland @basti_springer https://github.com/sspringer82 Monday, March 11, 13