Javascript Promise

Promise ist eine neue Technik, die mit ECMAScript 6 eingezogen ist und den Umgang mit asynchronem Verhalten sicherer und durch die then-Funktion lesbarer machen. Asynchron bedeutet, dass zwischen einer Anfrage und einer Antwort eine Verzögerung oder Wartezeit liegt.

18-12-15 SITEMAP

Callbacks bei zeitlich unbestimmbaren Abläufen

Wenn wir auf einen zeitlich nicht absehbaren Ablauf angewiesen sind – z.B. beim Laden eines Bildes oder einer json-Datei – werden Callbacks eingesetzt, die beim Eintreten eines Ereignisses aufgerufen werden.

Da die Callback-Funktion i.d.R. nur einmal aufgerufen werden, sehen wir sie oft als anonyme Funktion.

Promises ergänzen Callbacks, geben dem Code eine besser lesbare Struktur und zusätzliche Garantien, die den asynchronen Ablauf verläßlicher machen.

let arts;

function loadData (url) {
   const req = new XMLHttpRequest ();
   req.open ("GET", url);
   req.onload = function () {
      if (req.status === 200) {
         arts = JSON.parse (req.response);
         console.log (arts);
      }
   } // onload callback
   req.send();
} 

loadData ("arts.json");
console.log ("arts direct " + arts); 
let arts;

function loadData (url) {
   return new Promise (function (resolve, reject) {
      const req = new XMLHttpRequest ();
      req.open ("GET", url);
      req.onload = function () {
         if (req.status === 200) {
            resolve (JSON.parse (req.response));
         }
      } // onload callback
      req.send();
   });
} 

loadData ("fetch.json").then (function (data) {
   console.log ("arts promise " + data);
});

Javascript Promise

Die (linear betrachtet) zweite Log-Anweisung im linken Script gibt arts direct undefined zurück, denn entgegen der Reihenfolge im Code ist arts.json direkt nach loadData() wahrscheinlich noch nicht geladen.

Promises sind eine Schutzmaßnahme. Sie werden niemals vor dem Ende des Wartens auf ein Event aufgerufen und sie werden nur einmal ausgeführt. Gleich ob ein Promise erfüllt werden kann oder nicht, ruft es auf jeden Fall die korrekte Callback-Funktion auf. Darüber hinaus können Callbacks miteinander verketted (chained) werden: Dann ruft das Ergebnis einer Operation am Ende die nächste Operation auf.

Promise und then ()

Ein einfacher XMLHttpRequest mit nur einem asynchronen Request ist übersichtlich, aber sobald ein weiterer Request auf dem ersten Request beruht, wird der Code verschachtelt und unübersichtlich.

Promises stellen eine Methode then () zur Verfügung, die ausgeführt wird, nachdem das Versprechen eingelöst wurde. then () enthält zwei optionale Argumente: ein Callback für den Erfolg, ein Callback für den Fehlerfall.

So kann z.B. eine komplizierte Aktionsfolge aussehen, bei der zwei JSON-Dateien geladen werden sollen, wobei das Auslesen der zweiten JSON-Datei nur Sinn macht, wenn das erste JSON korrekt angeliefert wurde.

fetch ("listlib.json").then (function (response) {
	return response.json();
}).then (function (data) {
	appendData (data);			// listet die Thumbnails
}).then (function (bag) {
	fetch ("listlibkeys.json").
	then (function (response) {
		return response.json();
	}).then (function (bag) {
		listbagkeys (bag);		// erstellt die Schlüsselwortliste
	}).then (function (bag){ 
		countKeys();     	// wenn die Liste fertig erstellt wurde
	}).then (function (bag) {
		createListings ();
		setOptions();
	})
	}).catch (function (error) {
		console.log ("Fehler: " + error);
	});

then-Aufrufe können sequentiell aneinander gehangen werden, um zusätzliche asynchrone Aktionen nacheinander auszuführen (chaining).