Ajaxer

Javascript punks

29. November 2013
von Oliver Ochs
Keine Kommentare

JavaScript als funktionale Programmiersprache – Teil 8 – Callbacks

Erst Funktionen ermöglichen die effiziente Verarbeitung von asynchronen Programmabläufen. Fast jedes Programm lässt sich synchron schreiben. Angenommen, ein Programm lädt Daten über ein Netzwerk. Nachdem es diese Daten geladen hat, verarbeitet es diese Daten. Dies ließe sich wie folgt lösen.

var xhReq = new XMLHttpRequest(); xhReq.open("GET", "someURL", false); xhReq.send(null);
var daten = xhReq.responseText; print(daten);

Dieser Ansatz hat einen entscheidenden Nachteil. Das Programm wird blockiert, bis der Request abgearbeitet ist. Da JavaScript eine Sprache ist, die per Definition nur in einem Thread läuft, ist so lange der ganze Prozess oder Thread blockiert und benötigt Systemressourcen. Daher ist dieser blockierende Ansatz nicht zu empfehlen.
Besser ist der Ansatz, dies über Callbacks zu lösen. Dazu muss dem Request eine Callback-Funktion zur Verfügung gestellt werden. Funktionen sind Objekte. Darum können sie einer Funktion als Parameter übergeben werden. Diese übergebene Callback-Funktion wird dann aufgerufen, wenn der Request beendet ist und die Daten vorliegen. Der Request wartet nicht, bis die Response vorliegt, sondern kehrt sofort zurück.

request.on('response', function (response) { 
  response.on('data', function (daten) {
    console.log(daten);
  });
});

Diese Art der asynchronen Requests stellen Node (node.js) auf dem Server und Ajax-Frameworks im Webbrowser zur Verfügung. Node.js wird in im Buch ebenfalls besprochen.

Doch wie programmiert man selbst eine Funktion mit Callbacks. Als Beispiel schreiben wir eine Funktion, die eine lange Berechnung durchführt – die Summe aller Zahlen von eins bis eintausend. Diese Funktion wird zuerst synchron programmiert und anschließend zu einer asynchronen Callback-Funktion überarbeitet.

function calculate1To1000Synchronous() { 
  var result = 0;
  for (var i = 1; i < = 1000; i++) {
    result += i; 
   }
   return result;
}
var summe = calculate1To1000Synchronous(); 
console.log(summe); // 500500

Da in Wirklichkeit kein I/O durchgeführt wird, läuft diese Funktion nach dem Refactoring natürlich immer noch in einem einzigen Thread. Exemplarisch wird hier allerdings nun eine anonyme Callback-Funktion übergeben und nach der Berechnung des Werts aufgerufen.

function calculate1To1000WithCallback(callback) { 
  var result = 0;
  for (var i = 1; i < = 1000; i++) {
    result += i; 
  }
  callback(result);
}
calculate1To1000WithCallback(function(data) {
  console.log(data); // 500500
}); 

Cover-klein in JavaScript als funktionale Programmiersprache - Teil 8 - Callbacks - AjaxerDies ist eine autorisierte Leseprobe aus dem Buch Oliver Ochs – JavaScript für Enterprise-Entwickler: Professionell programmieren im Browser und auf dem Server – dpunkt.verlag GmbH 2012.

10. Juni 2013
von Oliver Ochs
Keine Kommentare

JavaScript als funktionale Programmiersprache – Teil 7 – Closures und Module

Closures und Module

Funktionen beinhalten Code. Eine Funktion wird stets in einem Funktionsgeltungsbereich ausgeführt. In der theoretischen Fachliteratur wird eine Kombination aus Code und Geltungsbereich als Closure bezeichnet.

Der Funktionsgeltungsbereich gilt auch, wenn in einer Funktion eine weitere, innere Funktion definiert wird. Diese Funktion hat dann Zugriff auf die Variablen der äußeren Funktion. Ausnahmen sind hier this und der Bonusparameter arguments, da diese Parameter von jeder Funktion selbst überschrieben werden, damit in der Scope-Kette die eigene this-Variable und der Bonusparameter arguments vor denen der äußeren Funktion gefunden werden.

Soll die this-Variable der äußeren Funktion der inneren Funktion zur Verfügung gestellt werden, so ist es üblich, in der äußeren Funktion eine that-Variable zu definieren und dieser die this-Variable zuzuweisen. Dann kann die innere Funktion über die that-Variable auf die this-Variable der äußeren Funktion zugreifen. Ein anderer üblicher Name für die that-Variable ist self. Dies ist aber verwirrend, da self in manchen Sprachen wie Smalltalk eigentlich der this-Variablen entspricht. Hier ein Beispiel für eine Closure.


    function outerFunction() {
       var x = "Hello";
       function innerFunction() {
           return x; 
       }
       return innerFunction();
    }
    console.log(outherFunction()); // Hello

Die innere Funktion innerFunction hat Zugriff auf die Variable x der äußeren Funktion outerFunction. Dieses Verhalten ist auf den ersten Blick nicht weiter überraschend. Interessant werden Closures, wenn eine innere Funktion zurückgegeben wird.

Diese innere Funktion hat nämlich Zugriff auf die Variablen der Funktion, in der sie definiert wurde. Diese Besonderheit wird in der Praxis als Closure bezeichnet.

Closures lassen sich verwenden, um private Variablen zu deklarieren. Man spricht dann von Modulen.

JavaScript kennt eigentlich keine privaten Variablen, aber es kennt Geltungsbereiche. Die folgende anonyme Funktion hat eine Variable variable. Auf diese Variable hat die innere Funktion inc Zugriff. Diese innere Funktion wird als Rückgabewert der Variablen incrementor zugewiesen. incrementor hat nun Zugriff auf die Funktion inc, nicht jedoch auf die Variable variable. Diese Variable erscheint nun wie eine private Variable.


    var incrementor = function () {
       var variable = 0;
       return {
          inc : function() {
             return variable ++;
          } 
       };
   }();
   console.log(incrementor.inc()); // 0 
   console.log(incrementor.inc()); // 1 
   console.log(incrementor.variable); // undefined

Wichtig zu verstehen ist, dass die innere Funktion wirklich Zugriff auf die Variablen der äußeren Funktion – das Activation-Objekt – hat und nicht nur auf eine Kopie. Wenn sich die Variable der äußeren Funktion verändert oder von der inneren Funktion verändert wird, so erfolgt der Zugriff zukünftig auf die geänderte Variable. Es lassen sich mit Closures also keine Zustände konservieren.

Cover-klein in JavaScript als funktionale Programmiersprache - Teil 7 - Closures und Module - AjaxerDies ist eine autorisierte Leseprobe aus dem Buch Oliver Ochs – JavaScript für Enterprise-Entwickler: Professionell programmieren im Browser und auf dem Server – dpunkt.verlag GmbH 2012.