Nico R.: Grundsätzliche Frage. Ist ein Callback hier der richtige Ansatz?

Beitrag lesen

Hallo Rolf,

das scheint in der Tat das zu sein, was ich suche. Die Beispiele auf der Mozilla-Seite sehen auf den ersten Blick hilfreich aus.

Allerdings werde ich das wohl nochmal etwas zurückstellen müssen, da mir doch so einige Grundlagen in objektorientierter Programmierung fehlen und ich mich da tiefer einarbeiten müsste. Die Zeit bzw. Ruhe hab ich zur Zeit leider nicht. Aber wenns soweit ist, werd ich hier sicher nochmal nachhaken.

Danke auf jeden Fall erstmal für deine Hinweise.

Gruß Nico

Hallo Nico R.,

Ließe sich das mit Promises klüger bewerkstelligen?

Ja. Promises haben concurrency-Methoden.

let p1 = fetchText("res1").then(processText1);
let p2 = fetchText("res2").then(processText2);

Promise.allSettled([p1, p2])
.then(button_einblenden);

Auf fetchText gehe ich gleich ein. Sie liefert ein Promise, sobald der Text verfügbar ist.

„Settled“ ist der Promise-Oberbegriff für resolved oder rejected. Die Promise.allSettled-Methode erzeugt ein neues Promise, das die an allSettled übergebenen Promises „bündelt“. Wenn alle Promises aus diesem Bündel resolved oder rejected wurden, resolved sich das Bündel-Promise. Der then-Handler bekommt ein Array mit allen Ergebnissen, für Details muss ich auf die MDN verweisen.

Wenn Du in den Verarbeitungsfunktionen processText1 und processText2 fertig bist, werden p1 und p2 resolved, und der Button erscheint. Letztlich passiert da genau das, was Du Dir schon selbst überlegt hast - aber so ist das Rad fertig und braucht keinen neuen Erfinder.

fetchText wäre mein Vorschlag für eine Funktion, die den Aufruf von fetch und den ersten .then-Handler bündelt, in dem Du den Erfolg der Operation abfragst.

Vorhin habe ich das als kleine Pfeilfunktion notiert:

.then(response => response.text())

aber das ist natürlich nicht produktionsreif. Unser Wiki zeigt auf der Seite für fetch ein etwas besseres Errorhandling. Den HTTP Status abzufragen kann man sich im ok-Fall sparen, ok ist nur true wenn der Status im 2xx-Bereich liegt (-> MDN)

Zum Beispiel so:

async function fetchText(ressource) {
   let response = await fetch(ressource);

   if (response.ok)
      return response.text();

   throw new Error("Fehler beim Laden von " + ressource);
}

Wenn Du nicht Text, sondern JSON vom Server bekommst, dann verwendest Du natürlich response.json() statt response.text(), um gleich das dekodierte Objekt zu erhalten, und nennst die Funktion fetchObject oder so.

Statt auf das allSettled-Promise mit then zu reagieren könnte man ebenfalls await verwenden, das hat aber die genannten Voraussetzungen (in async-Funktion notiert oder ein ECMAScript-Modul)

Beachte, dass die then-Callbacks nie zur gleichen Zeit aufgerufen werden, wenn der then läuft. D.h. direkt hinter dem then hast Du das Ergebnis der Operation, die ein Promise liefert, keinesfalls zur Verfügung. Die then-Callbacks werden grundsätzlich in der sogenannten Mikrotask-Queue ausgeführt, und das heißt: nach dem Ende des "normalen" JavaScript-Codes und vor dem Beginn der Layout-Phase des Browsers. async und await kaschieren das, aber auch da ist es so, dass aller Code, der den Rückgabewert eines await verarbeitet, in der Mikrotask-Queue ausgeführt wird.

Rolf