the event-driven nature of javascript – ipc2012
TRANSCRIPT
![Page 1: The event-driven nature of javascript – IPC2012](https://reader033.vdocuments.us/reader033/viewer/2022060201/559a6a1d1a28abdb348b47bd/html5/thumbnails/1.jpg)
THE EVENT-DRIVEN NATURE OF JAVASCRIPT
MARTIN SCHUHFUSS | SPOT-MEDIA AG
![Page 2: The event-driven nature of javascript – IPC2012](https://reader033.vdocuments.us/reader033/viewer/2022060201/559a6a1d1a28abdb348b47bd/html5/thumbnails/2.jpg)
ÜBER MICH
/ Hamburger
/ ursprünglich PHP-Entwickler
/ Javascript-Nerd, Performance-Fetischist
/ node.js und interactive-development
/ Architekt und Entwickler bei spot-media
MARTIN SCHUHFUSS@usefulthink
![Page 3: The event-driven nature of javascript – IPC2012](https://reader033.vdocuments.us/reader033/viewer/2022060201/559a6a1d1a28abdb348b47bd/html5/thumbnails/3.jpg)
UND IHR?
![Page 4: The event-driven nature of javascript – IPC2012](https://reader033.vdocuments.us/reader033/viewer/2022060201/559a6a1d1a28abdb348b47bd/html5/thumbnails/4.jpg)
JAVASCRIPT ?
![Page 5: The event-driven nature of javascript – IPC2012](https://reader033.vdocuments.us/reader033/viewer/2022060201/559a6a1d1a28abdb348b47bd/html5/thumbnails/5.jpg)
node.js ?
![Page 6: The event-driven nature of javascript – IPC2012](https://reader033.vdocuments.us/reader033/viewer/2022060201/559a6a1d1a28abdb348b47bd/html5/thumbnails/6.jpg)
WORUM GEHT‘S?
![Page 7: The event-driven nature of javascript – IPC2012](https://reader033.vdocuments.us/reader033/viewer/2022060201/559a6a1d1a28abdb348b47bd/html5/thumbnails/7.jpg)
THE EVENT-DRIVEN NATURE OF JAVASCRIPT
![Page 8: The event-driven nature of javascript – IPC2012](https://reader033.vdocuments.us/reader033/viewer/2022060201/559a6a1d1a28abdb348b47bd/html5/thumbnails/8.jpg)
SERVERSIDE JS ANDNON-BLOCKING I/O
![Page 9: The event-driven nature of javascript – IPC2012](https://reader033.vdocuments.us/reader033/viewer/2022060201/559a6a1d1a28abdb348b47bd/html5/thumbnails/9.jpg)
THE ASYNC NATURE OF JAVASCRIPT
![Page 10: The event-driven nature of javascript – IPC2012](https://reader033.vdocuments.us/reader033/viewer/2022060201/559a6a1d1a28abdb348b47bd/html5/thumbnails/10.jpg)
JAVASCRIPT EVENTS AND THE EVENT-LOOP
![Page 11: The event-driven nature of javascript – IPC2012](https://reader033.vdocuments.us/reader033/viewer/2022060201/559a6a1d1a28abdb348b47bd/html5/thumbnails/11.jpg)
zOMG, CALLBACKS EVERYWHERE
![Page 12: The event-driven nature of javascript – IPC2012](https://reader033.vdocuments.us/reader033/viewer/2022060201/559a6a1d1a28abdb348b47bd/html5/thumbnails/12.jpg)
JAVASCRIPT: THE BEST PART
![Page 13: The event-driven nature of javascript – IPC2012](https://reader033.vdocuments.us/reader033/viewer/2022060201/559a6a1d1a28abdb348b47bd/html5/thumbnails/13.jpg)
FIRST-CLASS FUNCTIONS/ Funktionen sind Objekte
/ …als Parameter
/ …als Rückgabewert
/ …in Variablenzuweisungen
/ Es gelten keine speziellen Regeln für Funktionen
/ Funktionen haben auch Eigenschaften und Methoden
/ z.B. fn.name oder fn.call() / fn.apply()
![Page 14: The event-driven nature of javascript – IPC2012](https://reader033.vdocuments.us/reader033/viewer/2022060201/559a6a1d1a28abdb348b47bd/html5/thumbnails/14.jpg)
FIRST-CLASS FUNCTIONS// a simple functionfunction something() { console.log("something"); }
// functions assigned as valuesvar aFunction = function() { /* ... */ }, somethingElse = something;
// function returning a functionfunction getFunction() { return function(msg) { console.log(msg); }}
var fn = getFunction();fn("foo"); // "foo"getFunction()("foo"); // works the same way!
![Page 15: The event-driven nature of javascript – IPC2012](https://reader033.vdocuments.us/reader033/viewer/2022060201/559a6a1d1a28abdb348b47bd/html5/thumbnails/15.jpg)
FIRST-CLASS FUNCTIONS
// functions as parametersfunction call(fn) { return fn();}
// passing an anonymous functioncall(function() { console.log("something");}); // "something"
![Page 16: The event-driven nature of javascript – IPC2012](https://reader033.vdocuments.us/reader033/viewer/2022060201/559a6a1d1a28abdb348b47bd/html5/thumbnails/16.jpg)
IMMEDIATE FUNCTIONS
(function __immediatelyExecuted() { console.log("something");} ());
// in short:(function() { ... } ());
unmittelbar nach Deklaration ausgeführte Funktionen
![Page 17: The event-driven nature of javascript – IPC2012](https://reader033.vdocuments.us/reader033/viewer/2022060201/559a6a1d1a28abdb348b47bd/html5/thumbnails/17.jpg)
CLOSURES
/ definieren scopes für Variablen
/ ermöglichen private Variablen
/ „einfrieren“ von Werten
/ Ermöglichen „konfigurierbare“ Funktionen
![Page 18: The event-driven nature of javascript – IPC2012](https://reader033.vdocuments.us/reader033/viewer/2022060201/559a6a1d1a28abdb348b47bd/html5/thumbnails/18.jpg)
CLOSURES
var deg2rad = (function() { var RAD_PER_DEG = Math.PI/180;
return function(deg) { return deg * RAD_PER_DEG; }}());
console.log(RAD_PER_DEG); // undefineddeg2Rad(180); // 3.1415926…
Scoping: „private“ Variablen
![Page 19: The event-driven nature of javascript – IPC2012](https://reader033.vdocuments.us/reader033/viewer/2022060201/559a6a1d1a28abdb348b47bd/html5/thumbnails/19.jpg)
CLOSURES
// for example to create a jQuery-plugin:(function($, window) { var somethingPrivate = null;
$.fn.extend({ plugin: function() { // here‘s the plugin-code
return this; } });} (this.jQuery, this));
ALLES ZUSAMMEN
![Page 20: The event-driven nature of javascript – IPC2012](https://reader033.vdocuments.us/reader033/viewer/2022060201/559a6a1d1a28abdb348b47bd/html5/thumbnails/20.jpg)
CLOSURES
var animate = (function(hasTransitions) { if(hasTransitions) { return function(params) { // animate using css-transitions }; } else { return function(params) { // animate using javascript, or better // don‘t animate at all. };}(Modernizr.csstransitions));
„Konfigurierbare“ Funktionen
![Page 21: The event-driven nature of javascript – IPC2012](https://reader033.vdocuments.us/reader033/viewer/2022060201/559a6a1d1a28abdb348b47bd/html5/thumbnails/21.jpg)
CLOSURES
for(var i=0; i<3; i++) { setTimeout(function() { console.log("i=" + i); }, 0);}
// -> i=3, i=3, i=3
there is no block-scope…
WTF?
![Page 22: The event-driven nature of javascript – IPC2012](https://reader033.vdocuments.us/reader033/viewer/2022060201/559a6a1d1a28abdb348b47bd/html5/thumbnails/22.jpg)
CLOSURES
for(var i=0; i<3; i++) { (function(value) { setTimeout(function() { console.log("i=" + value); }, 0); } (i));}
Closures zum „einfrieren“ von Variablen
// -> i=0, i=1, i=2
![Page 23: The event-driven nature of javascript – IPC2012](https://reader033.vdocuments.us/reader033/viewer/2022060201/559a6a1d1a28abdb348b47bd/html5/thumbnails/23.jpg)
NON-BLOCKING FUNCTIONS
![Page 24: The event-driven nature of javascript – IPC2012](https://reader033.vdocuments.us/reader033/viewer/2022060201/559a6a1d1a28abdb348b47bd/html5/thumbnails/24.jpg)
ASYNC FUNCTIONS
![Page 25: The event-driven nature of javascript – IPC2012](https://reader033.vdocuments.us/reader033/viewer/2022060201/559a6a1d1a28abdb348b47bd/html5/thumbnails/25.jpg)
ASYNC FUNCTIONSASYNC FUNCTIONS ARE JAVASCRIPTS
ANSWER TO position: absolute;Jed Schmidt, getting functional with (fab) – JSConf.eu 2010
![Page 26: The event-driven nature of javascript – IPC2012](https://reader033.vdocuments.us/reader033/viewer/2022060201/559a6a1d1a28abdb348b47bd/html5/thumbnails/26.jpg)
NON-BLOCKING FUNCTIONS
/ keine direkten Rückgabewerte
/ „Callbacks“ zur Fortsetzung des Programmablaufs
/ Background-Tasks übernehmen die Arbeit
/ keine Wartezeit innerhalb des Programms
![Page 27: The event-driven nature of javascript – IPC2012](https://reader033.vdocuments.us/reader033/viewer/2022060201/559a6a1d1a28abdb348b47bd/html5/thumbnails/27.jpg)
NON-BLOCKING FUNCTIONS
var r = new XMLHttpRequest();r.open("GET", "/foo/bar", true);
r.onreadystatechange = function () { if (r.readyState != 4 || r.status != 200) return;
console.log("Success: " + r.responseText);};
r.send();console.log("Request sent!");
doesn‘t block execution!
async „return“
![Page 28: The event-driven nature of javascript – IPC2012](https://reader033.vdocuments.us/reader033/viewer/2022060201/559a6a1d1a28abdb348b47bd/html5/thumbnails/28.jpg)
BLOCKING vs. NON-BLOCKING<?php
$browser = new Buzz\Browser();$response = $browser -> get('http://google.com');
echo $response;echo 'done!';
var http = require('http');
http.get('http://google.com', function(res) { console.log(res); });console.log('on the way!');
https://github.com/kriswallsmith/Buzz http://nodejs.org/api/http.html
![Page 29: The event-driven nature of javascript – IPC2012](https://reader033.vdocuments.us/reader033/viewer/2022060201/559a6a1d1a28abdb348b47bd/html5/thumbnails/29.jpg)
BLOCKING vs. NON-BLOCKING
WHERE IS THE DIFFERENCE?
![Page 30: The event-driven nature of javascript – IPC2012](https://reader033.vdocuments.us/reader033/viewer/2022060201/559a6a1d1a28abdb348b47bd/html5/thumbnails/30.jpg)
CPU-Registers(~1 cycle, 0.33 ns)
L1-Cache(~3 cycles, 1 ns)
L2-Cache(~14 cycles, 4.7 ns)
http://duartes.org/gustavo/blog/post/what-your-computer-does-while-you-wait
RAM(~250 cycles, 83 ns)
HDD-Seek(~41,000,000 cycles, ~13.7ms)
NETWORK(~240,000,000 cycles, ~80ms)
100
101
102
103
104
105
106
107
108
CP
UC
YCLE
S
if a single Instruction would take 1 second to execute, the HTTP-request to google.com would
require us to wait for 8 years and more.
BLOCKING vs. NON-BLOCKINGWHERE IS THE DIFFERENCE?
logarithmic scale!
![Page 31: The event-driven nature of javascript – IPC2012](https://reader033.vdocuments.us/reader033/viewer/2022060201/559a6a1d1a28abdb348b47bd/html5/thumbnails/31.jpg)
BLOCKING vs. NON-BLOCKING
<?php
$browser = new Buzz\Browser();$response = $browser -> get('http://google.com');
echo $response;echo 'done!';
WHERE IS THE DIFFERENCE?
Der php-Prozess blockiert während des Aufrufes und wird erst fortgesetzt, wenn $response verfügbar ist.
![Page 32: The event-driven nature of javascript – IPC2012](https://reader033.vdocuments.us/reader033/viewer/2022060201/559a6a1d1a28abdb348b47bd/html5/thumbnails/32.jpg)
BLOCKING vs. NON-BLOCKING
var http = require('http');
http.get('http://google.com', function(res) { console.log(res); });console.log('on the way!');
WHERE IS THE DIFFERENCE?
node.js kann weiterarbeiten, während der Request im
Hintergrund bearbeitet wird.
![Page 33: The event-driven nature of javascript – IPC2012](https://reader033.vdocuments.us/reader033/viewer/2022060201/559a6a1d1a28abdb348b47bd/html5/thumbnails/33.jpg)
BLOCKING vs. NON-BLOCKINGDIFFERENT SOLUTIONS
/ Threads bzw. Prozesse (apache/fcgi/…)
/ während ein Thread „schläft“ können andere Threads arbeiten
/ einfacher und intuitiver zu verstehen
/ Threads und Prozesse sind leider sehr teuer.
/ Event-Loops
/ Thread-Pools (Background-Tasks)
/ Alles wesentliche passiert in nur einem Prozess
/ Gehirnjogging – wann passiert was?
![Page 34: The event-driven nature of javascript – IPC2012](https://reader033.vdocuments.us/reader033/viewer/2022060201/559a6a1d1a28abdb348b47bd/html5/thumbnails/34.jpg)
INTRODUCING EVENTS
![Page 35: The event-driven nature of javascript – IPC2012](https://reader033.vdocuments.us/reader033/viewer/2022060201/559a6a1d1a28abdb348b47bd/html5/thumbnails/35.jpg)
INTRODUCING EVENTS
/ Ereignisse auf die in der Software reagiert werden kann
/ beliebig viele Quellen (üblicherweise nur eine)
/ beliebig viele Empfänger
![Page 36: The event-driven nature of javascript – IPC2012](https://reader033.vdocuments.us/reader033/viewer/2022060201/559a6a1d1a28abdb348b47bd/html5/thumbnails/36.jpg)
EVENTS IM BROWSER/ UI-events: resize, scroll, ...
/ user interaction-events: mouse*, key*, …
/ timer events: setTimeout(), setInterval()
/ render-events: requestAnimationFrame()
/ resource-events: load, readystatechange, …
/ navigation-events: hashchange, popstate, ...
/ communication-events: message, ...
![Page 37: The event-driven nature of javascript – IPC2012](https://reader033.vdocuments.us/reader033/viewer/2022060201/559a6a1d1a28abdb348b47bd/html5/thumbnails/37.jpg)
SERVER EVENTS
/ I/O-events (networking, http, filesystem, …)
/ timer-events
/ custom-events (emitted by modules)
![Page 38: The event-driven nature of javascript – IPC2012](https://reader033.vdocuments.us/reader033/viewer/2022060201/559a6a1d1a28abdb348b47bd/html5/thumbnails/38.jpg)
EVENT-HANDLING: CALLBACKS
/ vereinfachte Event-Verarbeitung
/ wird anstelle eines return-Wertes aufgerufen
/ Konvention: function callback(err, data) {}
![Page 39: The event-driven nature of javascript – IPC2012](https://reader033.vdocuments.us/reader033/viewer/2022060201/559a6a1d1a28abdb348b47bd/html5/thumbnails/39.jpg)
EVENT-HANDLING: EventEmitter/ Event-Quelle und Dispatcher
/ Listener für bestimmte Events werden mit on(evName, callback) angemeldet.
/ Events werden mit emit() (node.js) oder trigger() bzw. triggerHandler() (jQuery) ausgelöst
/ Events werden nur an die Listener für das Event in dem Event-Emitter gesendet.
![Page 40: The event-driven nature of javascript – IPC2012](https://reader033.vdocuments.us/reader033/viewer/2022060201/559a6a1d1a28abdb348b47bd/html5/thumbnails/40.jpg)
EVENT-HANDLING: EventEmitter
// Beispiel EventEmitter / node.js-defaultvar EventEmitter = require('events').EventEmitter, ee = new EventEmitter();
ee.on('food', function(data) { console.log('omnom!', data); });ee.emit('myCustomEvent', { cookies: true });
// Beispiel jQueryvar $doc = $(document);
$doc.on('food', function() { console.log('omnom', data); });$doc.triggerHandler('food', { cookies: true });
![Page 41: The event-driven nature of javascript – IPC2012](https://reader033.vdocuments.us/reader033/viewer/2022060201/559a6a1d1a28abdb348b47bd/html5/thumbnails/41.jpg)
REAL-LIFE EVENTS
![Page 42: The event-driven nature of javascript – IPC2012](https://reader033.vdocuments.us/reader033/viewer/2022060201/559a6a1d1a28abdb348b47bd/html5/thumbnails/42.jpg)
REAL-LIFE EVENTSRestaurant-Example
/ Ein Gast betritt ein Restaurant
/ … Kellner weist einen Tisch zu
/ … Kellner verteilt Speisekarten
/ Der Gast gibt eine Bestellung auf; der Kellner…
/ … gibt Getränkebestellungen an Barkeeper weiter
/ … gibt Essensbestellungen an Küche weiter
![Page 43: The event-driven nature of javascript – IPC2012](https://reader033.vdocuments.us/reader033/viewer/2022060201/559a6a1d1a28abdb348b47bd/html5/thumbnails/43.jpg)
restaurant.on('newGuestEnters', function(guests) { assignTable(guests);
guest.on('seated', function() { guests.handout(menue); });
// this might actually happen more than once... guests.on('order', function(order) { kitchenWorker.send(order.getMeals()); kitchenWorker.on('mealsReady', function(meals) { guest.deliver(meals); });
barkeeper.send(order.getDrinks()); barkeeper.on('drinksReady', function(drinks) { guest.deliver(drinks); }); });});
REAL-LIFE EVENTSRestaurant-Example
![Page 44: The event-driven nature of javascript – IPC2012](https://reader033.vdocuments.us/reader033/viewer/2022060201/559a6a1d1a28abdb348b47bd/html5/thumbnails/44.jpg)
REAL-LIFE EVENTS
LOOKS COMPLICATED?
Restaurant-Example
![Page 45: The event-driven nature of javascript – IPC2012](https://reader033.vdocuments.us/reader033/viewer/2022060201/559a6a1d1a28abdb348b47bd/html5/thumbnails/45.jpg)
while(true) { var guests = waitForGuests();
assignTable(guests); handoutMenues(guests);
var order; while(order = guests.getOrder()) { guests.deliver( makeDrinks(order) ); guests.deliver( makeFood(order) ); }}
REAL-LIFE EVENTSthe same, but with synchronous calls
![Page 46: The event-driven nature of javascript – IPC2012](https://reader033.vdocuments.us/reader033/viewer/2022060201/559a6a1d1a28abdb348b47bd/html5/thumbnails/46.jpg)
REAL-LIFE EVENTSthe same, but with synchronous calls
/ nur 1 Gast je Kellner
/ n gleichzeitige Gäste brauchen n Kellner (= Threads)
/ n Kellner und m>n Gäste: Warteschlange am Eingang
/ schlafende Kellner
![Page 47: The event-driven nature of javascript – IPC2012](https://reader033.vdocuments.us/reader033/viewer/2022060201/559a6a1d1a28abdb348b47bd/html5/thumbnails/47.jpg)
REAL-LIFE EVENTS
SO…
![Page 48: The event-driven nature of javascript – IPC2012](https://reader033.vdocuments.us/reader033/viewer/2022060201/559a6a1d1a28abdb348b47bd/html5/thumbnails/48.jpg)
restaurant.on('newGuestEnters', function(guests) { waiter.assignTable(guests);
guests.on('seated', function() { guests.handout(menue);
// this might actually happen more than once... guests.on('order', function(order) { kitchenWorker.send(order.getMeals()); kitchenWorker.on('mealsReady', function(meals) { guests.deliver(meals); }); barkeeper.send(order.getDrinks()); barkeeper.on('drinksReady', function(drinks) { guests.deliver(drinks); }); }); });});
REAL-LIFE EVENTSasync is winning!
![Page 49: The event-driven nature of javascript – IPC2012](https://reader033.vdocuments.us/reader033/viewer/2022060201/559a6a1d1a28abdb348b47bd/html5/thumbnails/49.jpg)
REAL-LIFE EVENTSasync is winning!
/ nur 1 Kellner für n gleichzeitige Gäste
/ zu viele Gäste führen zu langsamerer Asuführung
/ Zubereitung wird von Hintergrund-Services erledigt (barkeeper/kitchenWorker)
/ jegliche Aktion wird über Events ausgelöst
/ Kellner sind nur untätig, wenn
![Page 50: The event-driven nature of javascript – IPC2012](https://reader033.vdocuments.us/reader033/viewer/2022060201/559a6a1d1a28abdb348b47bd/html5/thumbnails/50.jpg)
restaurant.on('newGuestEnters', function(guests) { waiter.assignTable(guests);
guests.on('seated', function() { guests.handout(menue);
// this might actually happen more than once... guests.on('order', function(order) { kitchenWorker.send(order.getMeals()); kitchenWorker.on('mealsReady', function(meals) { guests.deliver(meals); }); barkeeper.send(order.getDrinks()); barkeeper.on('drinksReady', function(drinks) { guests.deliver(drinks); }); }); });});
REAL-LIFE EVENTSasync is winning!
![Page 51: The event-driven nature of javascript – IPC2012](https://reader033.vdocuments.us/reader033/viewer/2022060201/559a6a1d1a28abdb348b47bd/html5/thumbnails/51.jpg)
THE EVENT-LOOP
![Page 52: The event-driven nature of javascript – IPC2012](https://reader033.vdocuments.us/reader033/viewer/2022060201/559a6a1d1a28abdb348b47bd/html5/thumbnails/52.jpg)
THE EVENT-LOOP
MAIN-PROCESSfile = fs.createReadStream(...);file.on('data', myCallback);
BASIC ARCHITECTURE
the code in the main program is executed and registers event-
handlers for certain events.
1WORKER
THREADS
long-running operations (I/O) are handled by
worker-threads
2
![Page 53: The event-driven nature of javascript – IPC2012](https://reader033.vdocuments.us/reader033/viewer/2022060201/559a6a1d1a28abdb348b47bd/html5/thumbnails/53.jpg)
WORKERTHREADS
THE EVENT-LOOPBASIC ARCHITECTURE
MAIN-PROCESSfile = fs.createReadStream(...);file.on('data', myCallback);
EVENT-LOOP
EVENT-QUEUE
once all code is executed, the event-loop starts
waiting for incoming events.
3
![Page 54: The event-driven nature of javascript – IPC2012](https://reader033.vdocuments.us/reader033/viewer/2022060201/559a6a1d1a28abdb348b47bd/html5/thumbnails/54.jpg)
WORKERTHREADS
THE EVENT-LOOPBASIC ARCHITECTURE
MAIN-PROCESSfile = fs.createReadStream(...);file.on('data', myCallback);
EVENT-LOOP
EVENT-QUEUE
background-threads eventually fire events
to send data to the main-program
4
fs.data
http.request
fs.end
![Page 55: The event-driven nature of javascript – IPC2012](https://reader033.vdocuments.us/reader033/viewer/2022060201/559a6a1d1a28abdb348b47bd/html5/thumbnails/55.jpg)
WORKERTHREADS
THE EVENT-LOOPBASIC ARCHITECTURE
MAIN-PROCESSmyCallback(data);
EVENT-LOOP
EVENT-QUEUEhttp.request
fs.end
for each event, the associated callbacks are executed in the
main process
5fs.datafs.data
![Page 56: The event-driven nature of javascript – IPC2012](https://reader033.vdocuments.us/reader033/viewer/2022060201/559a6a1d1a28abdb348b47bd/html5/thumbnails/56.jpg)
WORKERTHREADS
THE EVENT-LOOPBASIC ARCHITECTURE
MAIN-PROCESSprocess.nextTick(callback);setTimeout(callback, 0);
http.request
fs.end
it is possible to add custom events to the
event-queue
5
tickEvent
timerEvent
![Page 57: The event-driven nature of javascript – IPC2012](https://reader033.vdocuments.us/reader033/viewer/2022060201/559a6a1d1a28abdb348b47bd/html5/thumbnails/57.jpg)
THE EVENT-LOOPZUSAMMENFASSUNG
/ keine Parallelisierung
/ Verarbeitung in Reihenfolge der Erzeugung
/ alles wesentliche in nur einem Prozess
/ separate Prozesse für CPU-Intensive Tasks
/ zwingt zum Schreiben von asynchronem Code
![Page 58: The event-driven nature of javascript – IPC2012](https://reader033.vdocuments.us/reader033/viewer/2022060201/559a6a1d1a28abdb348b47bd/html5/thumbnails/58.jpg)
THE EVENT-LOOP
NEVER BLOCK THE EVENT-LOOP
![Page 59: The event-driven nature of javascript – IPC2012](https://reader033.vdocuments.us/reader033/viewer/2022060201/559a6a1d1a28abdb348b47bd/html5/thumbnails/59.jpg)
$('.oh-my').on('click', function(req, res) { $.ajax('/somewhere', { async: false, complete: function(jqXHR, respText) { console.log('we‘re done!'); } });
console.log('waited soo long!');});
NEVER BLOCK THE EVENT-LOOP – BROWSER EDITIONTHE EVENT-LOOP
everytime someone makes a synchronous XHR, god kills a kitten.
will block the event-loopAND the UI-Thread
is executed AFTER the theXHR completes
![Page 60: The event-driven nature of javascript – IPC2012](https://reader033.vdocuments.us/reader033/viewer/2022060201/559a6a1d1a28abdb348b47bd/html5/thumbnails/60.jpg)
var running = true;
process.nextTick(function() { running = false;});
while(running) { // ...whatever...}
NEVER BLOCK THE EVENT-LOOP – SERVER EDITIONTHE EVENT-LOOP
is never called!
…because this never returns
![Page 61: The event-driven nature of javascript – IPC2012](https://reader033.vdocuments.us/reader033/viewer/2022060201/559a6a1d1a28abdb348b47bd/html5/thumbnails/61.jpg)
var http = require('http'), webserver = http.createServer();
webserver.on('request', function(req, res) { // some long-running calculation (e.g. image-processing) // or synchronous call
res.end('finally done!');});
THE EVENT-LOOP
no further request-processing while this is running
NEVER BLOCK THE EVENT-LOOP – SERVER EDITION
![Page 62: The event-driven nature of javascript – IPC2012](https://reader033.vdocuments.us/reader033/viewer/2022060201/559a6a1d1a28abdb348b47bd/html5/thumbnails/62.jpg)
var http = require('http'), asyncService = require('./asyncService'), webserver = http.createServer();
webserver.on('request', function(req, res) { asyncService.startLongRunningOperation(); asyncService.on('completed', function() { res.end('finally done!'); });});
ASYNC FTW!THE EVENT-LOOP
doesn‘t block
![Page 63: The event-driven nature of javascript – IPC2012](https://reader033.vdocuments.us/reader033/viewer/2022060201/559a6a1d1a28abdb348b47bd/html5/thumbnails/63.jpg)
// asyncService.jsvar spawn = require('child_process').spawn, EventEmitter = require('events').EventEmitter,
service = new EventEmitter();
service.startLongRunningOperation = function() { var child = spawn('sleep', [ 2 ]); child.on('exit', function(code) { service.emit('completed'); });};
module.exports = service;
ASYNC FTW!THE EVENT-LOOP
takes 2 seconds to complete
![Page 64: The event-driven nature of javascript – IPC2012](https://reader033.vdocuments.us/reader033/viewer/2022060201/559a6a1d1a28abdb348b47bd/html5/thumbnails/64.jpg)
$('#foo').on('click', function(ev) { // first part of something that takes some time
window.setTimeout(function() { // second part... }, 0);});
ASYNC FTW (BROWSER-EDITION)!THE EVENT-LOOP
„pushed back“, allows other events to be processed in the meantime
![Page 65: The event-driven nature of javascript – IPC2012](https://reader033.vdocuments.us/reader033/viewer/2022060201/559a6a1d1a28abdb348b47bd/html5/thumbnails/65.jpg)
ASYNC FTW!THE EVENT-LOOP
/ Wenns mal zu lange dauert:
/ child-process in node.js
/ web-worker im browser
/ „split and defer“: setTimeout(continuation, 0);
![Page 66: The event-driven nature of javascript – IPC2012](https://reader033.vdocuments.us/reader033/viewer/2022060201/559a6a1d1a28abdb348b47bd/html5/thumbnails/66.jpg)
zOMG, CALLBACKS EVERYWHERE
![Page 67: The event-driven nature of javascript – IPC2012](https://reader033.vdocuments.us/reader033/viewer/2022060201/559a6a1d1a28abdb348b47bd/html5/thumbnails/67.jpg)
CALLBACK-HELLrestaurant.on('newGuestEnters', function(guests) { assignTable(guests);
guests.on('seated', function() { guests.handout(menue);
// this might actually happen more than once... guests.on('order', function(order) { kitchenWorker.send(order.getMeals()); kitchenWorker.on('mealsReady', function(meals) { guests.deliver(meals); }); barkeeper.send(order.getDrinks()); barkeeper.on('drinksReady', function(drinks) { guests.deliver(drinks); }); }); });});
![Page 68: The event-driven nature of javascript – IPC2012](https://reader033.vdocuments.us/reader033/viewer/2022060201/559a6a1d1a28abdb348b47bd/html5/thumbnails/68.jpg)
CALLBACK-HELL
COULD BE EVEN WORSE
![Page 69: The event-driven nature of javascript – IPC2012](https://reader033.vdocuments.us/reader033/viewer/2022060201/559a6a1d1a28abdb348b47bd/html5/thumbnails/69.jpg)
restaurant.on('newGuestEnters', function(guests) { assignTable(guests);
guests.on('seated', function() { guests.handout(menue); attachOrderHandling(guests); });});
function attachOrderHandling(guests) { guests.on('order', function(order) { kitchenWorker.send(order.getMeals()); kitchenWorker.on('mealsReady', function(meals) { guests.deliver(meals); });
barkeeper.send(order.getDrinks()); barkeeper.on('drinksReady', function(drinks) { guests.deliver(drinks); }); });}
CALLBACK-HELLSOLUTION: EXTRACT FUNCTIONS
![Page 70: The event-driven nature of javascript – IPC2012](https://reader033.vdocuments.us/reader033/viewer/2022060201/559a6a1d1a28abdb348b47bd/html5/thumbnails/70.jpg)
WHAT IF FUNCTIONS DEPEND ON EACH OTHER?
![Page 71: The event-driven nature of javascript – IPC2012](https://reader033.vdocuments.us/reader033/viewer/2022060201/559a6a1d1a28abdb348b47bd/html5/thumbnails/71.jpg)
Step( function readSelf() { fs.readFile(__filename, this); }, function capitalize(err, text) { if(err) { throw err; } return text.toUpperCase(); }, function showIt(err, newText) { if(err) { throw err; } console.log(newText); });
CALLBACK-HELLUSE Step()
https://github.com/creationix/step
![Page 72: The event-driven nature of javascript – IPC2012](https://reader033.vdocuments.us/reader033/viewer/2022060201/559a6a1d1a28abdb348b47bd/html5/thumbnails/72.jpg)
WHAT IF WE NEED MULTIPLE RESPONSES
![Page 73: The event-driven nature of javascript – IPC2012](https://reader033.vdocuments.us/reader033/viewer/2022060201/559a6a1d1a28abdb348b47bd/html5/thumbnails/73.jpg)
Step( // Loads two files in parallel function loadStuff() { fs.readFile(__filename, this.parallel()); fs.readFile("/etc/passwd", this.parallel()); }, // Show the result when done function showStuff(err, code, users) { if (err) throw err;
console.log(code); console.log(users); })
CALLBACK-HELLUSE Step()
![Page 74: The event-driven nature of javascript – IPC2012](https://reader033.vdocuments.us/reader033/viewer/2022060201/559a6a1d1a28abdb348b47bd/html5/thumbnails/74.jpg)
QUESTIONS?
![Page 75: The event-driven nature of javascript – IPC2012](https://reader033.vdocuments.us/reader033/viewer/2022060201/559a6a1d1a28abdb348b47bd/html5/thumbnails/75.jpg)
THANKS!
FEEDBACK https://joind.in/7340 MARTIN SCHUHFUSS@usefulthinkSLIDES https://speakerdeck.com/u/usefulthink