Dr. Web Logo. Untertext: Seit 1997.
  • Beste Agenturen
  • Agentur-Standorte von A bis Z 🌇
  • Magazin
  • Newsletter 📩
  • Login
  • Agentur bewerben ✅
  • Kontakt
  • Werben 🎉
  • Sponsored Post
  • Jobs
Menü
  • Beste Agenturen
  • Agentur-Standorte von A bis Z 🌇
  • Magazin
  • Newsletter 📩
  • Login
  • Agentur bewerben ✅
  • Kontakt
  • Werben 🎉
  • Sponsored Post
  • Jobs
  • Werben
  • Gastbeitrag
  • Sponsored Post
  • Kontakt
  • Login
  • Newsletter
Suche
  • Beste Agenturen
  • Agentur-Standorte
      Berlin bei Nacht, Blick von oben Richtung Fernsehturm.

      Berlin

      Blick auf die Elbufer-Promenade Dresdens sowie Frauenkirche und Zwinger.

      Dresden

      Düsseldorf von oben mit Blick auf den Fernsehturm.

      Düsseldorf

      Blick von oben auf das Bankenviertel in Frankfurt am Main.

      Frankfurt am Main

      Hamburg bei Nacht, Blick auf die Speicherstadt.

      Hamburg

      Blick auf das Neue Rathaus, Hannover.

      Hannover

      Agenturen in Innsbruck von oben mit Blick auf die Alpen.

      Innsbruck

      Sonnenuntergang in Köln mit Blick auf den Dom. Im Vordergrund die Hohenzollernbrücke.

      Köln

      München bei Fön mit Blick in die bayerischen Alpen.

      München

      Stuttgart von oben.

      Stuttgart

      Wien von oben. Blick auf den Stephansdom.

      Wien

      Zürich von oben.

      Zürich

  • Magazin
    • Content Marketing
    • CSS
    • E-Commerce
    • E-Mail-Marketing
    • Freelancer
    • Fotografie
    • HTML
    • Online-Marketing
    • Responsive Design
    • SEO
    • UX Design
    • Webdesign
    • Website erstellen
    • WordPress
    • Dr. Web Autoren
  • Jobs
Menü
  • Magazin
    • Content Marketing
    • CSS
    • E-Commerce
    • E-Mail-Marketing
    • Freelancer
    • Fotografie
    • HTML
    • Online-Marketing
    • Responsive Design
    • SEO
    • UX Design
    • Webdesign
    • Website erstellen
    • WordPress
    • Dr. Web Autoren
  • Jobs
Agentur eintragen →
Dr. Web Logo. Untertext: Seit 1997.
  • Beste Agenturen
  • Agentur-Standorte
      Berlin bei Nacht, Blick von oben Richtung Fernsehturm.

      Berlin

      Blick auf die Elbufer-Promenade Dresdens sowie Frauenkirche und Zwinger.

      Dresden

      Düsseldorf von oben mit Blick auf den Fernsehturm.

      Düsseldorf

      Blick von oben auf das Bankenviertel in Frankfurt am Main.

      Frankfurt am Main

      Hamburg bei Nacht, Blick auf die Speicherstadt.

      Hamburg

      Blick auf das Neue Rathaus, Hannover.

      Hannover

      Agenturen in Innsbruck von oben mit Blick auf die Alpen.

      Innsbruck

      Sonnenuntergang in Köln mit Blick auf den Dom. Im Vordergrund die Hohenzollernbrücke.

      Köln

      München bei Fön mit Blick in die bayerischen Alpen.

      München

      Stuttgart von oben.

      Stuttgart

      Wien von oben. Blick auf den Stephansdom.

      Wien

      Zürich von oben.

      Zürich

Agentur eintragen →
Dr. Web » JavaScript & jQuery » JavaScript: mit nativen Promises auf Callback-Verschachtelungen verzichten

JavaScript: mit nativen Promises auf Callback-Verschachtelungen verzichten

Sozial sein
Share on facebook
Share on twitter
Share on linkedin
Share on xing
Share on whatsapp
Share on email
  • Ein Kommentar
Lesedauer: 6 Minuten
  • von Denis Potschien
  • 8. Mai 2015
Bookmarke mich
Share on pocket

Viele JavaScript-Frameworks wie jQuery und AngularJS kennen sogenannte Promises. Sie ermöglichen es, das Ergebnis asynchroner Aufrufe festzustellen und auf jenes Ergebnis zuzugreifen. Dabei lassen sich mehrere asynchrone Aufrufe „in Reihe schalten“. So wird erreicht, dass ein Aufruf erst gestartet wird, wenn ein anderer Aufruf bereits erfolgreich abgeschlossen wurde. Mittlerweile gibt es Promises auch als natives JavaScript-Objekt. So kann es ohne zusätzliche Frameworks und Bibliotheken eingesetzt werden.

JavaScript Promises

Wozu braucht man Promises?

Gerade in komplexen Webanwendungen kommt man ganz oft nicht umhin, per Events und Callbacks festzustellen, ob eine Operation erfolgreich abgeschlossen werden konnte – beispielsweise, wenn man Inhalte per „XMLHttpRequest()“ lädt und diese anschließend weiterverarbeiten will. Mit dem „load“-Event lässt sich hier über eine Callback-Funktion feststellen, wie der aktuelle Status des „XMLHttpRequest()“-Aufrufs ist.

function bild_laden(url) {
  var datei = new XMLHttpRequest();
  datei.open("GET", url);
  datei.addEventListener("load", function() {
    if (this.status == 200) {
      console.log(url + " geladen.");
    } else {
      console.log(url + "nicht geladen.");
    }
  }, false);
  datei.send();
}

bild_laden("bild.jpg");

Das simple Beispiel zeigt, wie Callbacks funktionieren. Das „load“-Event ruft eine Funktion auf, sobald der XMLHttpRequest()“-Aufruf erfolgreich war oder gescheitert ist. Der Status 200 im Beispiel wird ausgegeben, wenn das Laden erfolgreich war. Schwierig wird es allerdings, wenn beispielsweise eine zweite Datei geladen werden soll – und zwar, nachdem die erste geladen wurde.

bild_laden("bild1.jpg");
bild_laden("bild2.jpg");

Man kann natürlich die Funktion zweimal aufrufen und die beiden zu ladenden Dateinamen übergeben. Allerdings weiß man nie, welcher der beiden Requests als erster fertig ist. Bei den beiden Bildern im Beispiel dürfte es egal sein, welche Datei zuerst geladen wurde. Aber es gibt immer wieder Abläufe, bei denen man sicherstellen muss, dass bestimmte Inhalte bereits zur Verfügung stehen, bevor andere Inhalte geladen oder andere Operationen ausgeführt werden.

Jetzt kann man sich unterschiedlich behelfen, um festzustellen, ob eine Datei bereits geladen wurde. Man kann beispielsweise Events und die dazugehörigen Callback-Funktionen verschachteln.

function bild_laden(url1, url2) {
  var datei1 = new XMLHttpRequest();
  datei1.open("GET", url1);
  datei1.addEventListener("load", function() {
    if (this.status == 200) {
      console.log(url + " geladen.");
      var datei2 = new XMLHttpRequest();
      datei2.open("GET", url2);
      datei2.addEventListener("load", function() {
        if (this.status == 200) {
          console.log(url + " geladen.");
        } else {
          console.log(url + " nicht geladen.");
        }
      }, false);
      datei2.send();
    } else {
      console.log(url + " nicht geladen.");
    }
  }, false);
  datei1.send();
}

bild_laden("bild.jpg", "bild.jpg");

Das zweite Beispiel zeigt, dass bereits die Verschachtelung zweier Callback-Funktionen die ganze Sache recht komplex macht. Zwar erreicht man, dass die zweite Datei erst geladen wird, nachdem die erste erfolgreich geladen wurde. Kommen allerdings noch weitere Aufrufe dazu, die vom Erfolg anderer Aufrufe abhängig gemacht werden sollen, wird es für Programmierer oft sehr unübersichtlich. Nicht ohne Grund nennt man diese Problematik auch „Pyramid of Doom“.

Mit Promises gibt es eine wesentlich elegantere Möglichkeit, den Erfolg verschiedener Operationen festzustellen. Statt verschachtelter Callback-Funktionen wird der Erfolg beziehungsweise Misserfolg über ein sogenanntes Promise-Objekt festgestellt. Dabei haben Promises noch weitere Vorteile gegenüber einfacher Callbacks, die an späterer Stelle noch vorgestellt werden.

Neuen Promise anlegen

Um mit Promises zu arbeiten, muss zunächst ein neues Promise-Objekt angelegt werden. Diesem wird eine Funktion zugewiesen, die zwei Werte zurückgibt:

Der erste Wert – „Resolve“ genannt – wird zurückgegeben, wenn der Promise erfolgreich war, der zweite Wert – „Reject“ genannt –, wenn der Promise nicht erfolgreich war.

function bild_laden(url) {
  return new Promise(function(erfolg, misserfolg) {
    var datei = new XMLHttpRequest();
    datei.open("GET", url);
    datei.addEventListener("load", function() {
      if (this.status == 200) {
        erfolg(url + " geladen.");
      } else {
        misserfolg(url + " nicht geladen.");
      }
    }, false);
    datei.send();
  });
}

Im Beispiel wird der Funktion „bild_laden()“ per „return“ ein neues Promise-Objekt hinzugefügt. Das „return“ sorgt dafür, dass die Funktion das Ergebnis des Promises zurückgibt – also die Werte für „Resolve“ beziehungsweise „Reject“. Das Promise-Objekt enthält wiederum eine Funktion, die per „XMLHttpRequest()“ eine Datei lädt. Im Grunde wird dasselbe gemacht wie im ersten Beispiel. Auch hier wird per Callback-Funktion über das „load“-Event geprüft, ob die Datei geladen wurde oder nicht. Im Erfolgsfall wird dem „Resolve“ mit der Bezeichnung „erfolg“ ein Wert zugewiesen. Dieser Wert kann frei vergeben werden. Dem „Resolve“ kann auch der Inhalt der geladenen Datei („datei.response“) übergeben werden. So kann man später darauf zugreifen.

Der Wert für „Reject“ – im Beispiel „misserfolg“ – kann ebenfalls frei vergeben werden. Dieser wird meist verwendet, um eine Fehlermeldung auszugeben.

Der große Vorteil der Promises ist, dass das erfolgreiche Laden der Datei per „XMLHttpRequest()“ jenseits der Funktion „bild_laden()“ geprüft werden kann. Man muss Callback-Funktionen also nicht verschachteln. Dafür stehen die beiden Methoden „then()“ und „catch()“ zur Verfügung.

bild_laden("bild.jpg").then(
  function(erfolg) {
   console.log(erfolg);
  }
).catch(
  function(misserfolg) {
    console.log(misserfolg);
  }
);

Im Beispiel wird das Promise-Objekt beziehungsweise die Funktion „bild_laden()“ aufgerufen, um eine Datei zu laden. Die Methode „then()“ des Promise-Objektes wird dann ausgeführt, wenn der Promise erfolgreich war – die Datei also geladen wurde. Andernfalls wird die „catch()“-Methode ausgeführt. Während der „then()“-Methode der Inhalt von „Resolve“ – im Beispiel „erfolg“ – übergeben wird, erhält die „catch()“-Methode den Inhalt von „Reject“ – im Beispiel „misserfolg“. Über eine Funktion können die Inhalte der beiden übergebenen Variablen ausgegeben oder anderweitig verarbeitet werden. Im Beispiel werden die Werte einfach in die Konsole geschrieben.

Um mehrere Promise-Aufrufe „in Reihe zu schalten“, genügt es, mehrere „then()“-Methoden miteinander zu verketten. So wird erreicht, dass die erste „then()“-Methode erst dann aufgerufen wird, wenn der erste Promise erfolgreich war.

bild_laden("bild1.jpg").then(
  bild_laden("bild2.jpg")
).then(
  bild_laden("bild3.jpg")
).catch(
  function(misserfolg) {
    console.log(misserfolg);
  }
);

Das Beispiel zeigt, wie einfach Aufrufe verkettet werden können. Nachdem die Datei „bild1.jpg“ erfolgreich geladen wurde, wird per „then()“ die Datei „bild2.jpg“ geladen. Ist auch diese Datei geladen, wird eine dritte Datei geladen. Die „catch()“-Methode im Beispiel wird aufgerufen, wenn die erste Datei nicht geladen werden konnte – der erste Promise also erfolglos war.

Natürlich kann für jeden einzelnen Aufruf eine „catch()“-Methode ergänzt werden. So lässt sich jeder nicht erfolgreiche Aufruf der Funktion abfangen.

bild_laden("bild1.jpg").then(
  bild_laden("bild2.jpg")
).then(
  bild_laden("bild3.jpg").catch(
    function(misserfolg) {
      console.log(misserfolg);
    }
  )
).then(
  bild_laden("bild2.jpg").catch(
    function(misserfolg) {
      console.log(misserfolg);
    }
  )
).catch(
  function(misserfolg) {
    console.log(misserfolg);
  }
);

Dieses Beispiel zeigt, wie für jeden Aufruf der Funktion „bild_laden()“ eine entsprechende „catch()“-Methode ergänzt wurde. So entgeht einem kein erfolgloser Promise.

Ein Promise kann einen von drei Stati besitzen. Während geprüft wird, ob ein Promise erfüllt ist oder nicht, besitzt er den Status „pending“. Ist er erfüllt, hat er den Status „fulfilled“. Scheitert ein Promise, ist sein Status „rejected“. Der Status selbst lässt sich nicht abfragen, ist für das Verständnis von Promises aber nicht unwichtig.

Promises als Array übergeben und prüfen

Statt einzelne Funktionen per „then()“ aneinanderzuketten, gibt es auch eine einfachere Möglichkeit. Die Methode „all()“ erlaubt es, Funktionen beziehungsweise Promise-Objekte als Array zu übergeben und dieses Array als Ganzes zu prüfen.

Promise.all([bild_laden("bild1.jpg"), bild_laden("bild2.jpg")]).then(
  function (erfolg) {
    console.log(erfolg);
  }
);

Im Beispiel werden die einzelnen Aufrufe von „bild_laden()“ als Array der „all()“-Methode übergeben. Der Vorteil ist die wesentliche kürzere Auszeichnung. Allerdings hat man hierbei keine Möglichkeit, auf einzelne Misserfolge zu reagieren. Die „then()“-Methode wird nur dann ausgeführt, wenn alle Promises im Array erfüllt werden – also alle Dateien geladen sind. Sobald ein Promise im Array erfolglos war, gibt „all()“ für den gesamten Array den Status „rejected“ aus. Allerdings werden beim Status „fulfilled“ alle Rückgabewerte des Arrays („erfolg“) ausgegeben. Diese werden ebenfalls als Array bereitgestellt und im Beispiel in die Konsole geschrieben.

Schnellste Funktion wiedergeben

Neben der Methode „all()“ gibt es noch die Methode „race()“, bei der verschiedene Promises ebenfalls als Array übergeben werden. Statt alle Promises auszuführen und wiederzugeben, trifft das bei „race()“ nur auf den ersten erfolgreichen oder gescheiterten Promise zu.

Promise.race([bild_laden("bild1.jpg"), bild_laden("bild2.jpg")]).then(
  function (erfolg) {
    console.log(erfolg);
  }
);

Im Beispiel wird also nur für den ersten Promise, der erfolgreich oder nicht erfolgreich war, die Methode „then()“ aufgerufen. Relevant ist hierbei nur, welcher der Promises als erster einen Erfolg oder Misserfolg meldet.

Verkürzte Schreibweise für „catch()“

Auf die Auszeichnung der „catch()“-Methode kann auch verzichtet werden. Es gibt eine verkürzte Möglichkeit. Der „then()“-Methode können zwei Funktionen übergeben werden. Die erste der Funktionen wird dann beim Erfolg eines Promises ausgeführt, die zweite beim Misserfolg. Die zweite Funktion entspricht also der innerhalb der „catch()“-Methode.

bild_laden("bild.jpg").then(
  function(erfolg) {
    console.log(erfolg);
  }, function(misserfolg) {
    console.log(misserfolg);
  }
);

Die beiden Funktionen werden einfach per Komma voneinander getrennt. Will man nur eine Funktion für den Misserfolg definieren, genügt es, anstelle der ersten Funktion ein „undefined“ zu notieren.

Promises testen mit „resolve()“ und „reject()“

Mit den beiden Methoden „resolve()“ und „reject()“ kann man den Erfolg beziehungsweise Misserfolg eines Promises testen. Die „resolve()“-Methode gibt immer ein Promise-Objekt wieder, welches erfolgreich war – unabhängig davon, ob es tatsächlich von Erfolg gekrönt war. Die „reject()“-Methode hingegen stuft ein Promise-Objekt immer als nicht erfolgreich ein. In beiden Fällen werden die jeweiligen Werte von „Resolve“ beziehungsweise „Reject“ an die Methoden übergeben.

Promise.reject(bild_laden("bild1.jpg")).catch(
  function(misserfolg) {
    console.log(misserfolg);
  }
);

Im Beispiel wird per „reject()“ dafür gesorgt, dass die Funktion beziehungsweise das Promise-Objekt „bild_laden()“ als nicht erfolgreich wiedergegeben wird. Da die „then()“-Methode nur im Erfolgsfall aufgerufen wird, muss sie nicht aufgeführt werden. Denn dieser wird bei der „reject()“-Methode nie eintreten. Daher genügt es, die „catch()“-Methode aufzurufen.

Browsersupport und Polyfills

Promises laufen unter Chrome ab Version 32, Firefox ab Version 29 und Opera ab Version 19. Beim Internet Explorer sind Promises in der Entwicklung und werden möglicherweise in der nächsten Verison unterstützt. Es gibt auch ein Polyfill, der Promises für ältere Browser nachbildet.

Neben dem nativen Promise-Objekt und den Implementierungen in verschiedenen Frameworks wie jQuery und AngularJS gibt es auch Standalone-Frameworks für Promises. Dazu zählen unter anderem „Q“ sowie „Promise.js“. Diese Frameworks sollte man nicht vernachlässigen, nur weil es jetzt eine native JavaScript-Möglichkeit für Promises gibt. Denn die Promise-Objekte der Frameworks haben teils umfangreichere Features als das, was JavaScript nativ derzeit anbietet. Wer sich also weiter mit Promises auseinandersetzen will, sollte „Q“, „Promise.js“ und den anderen Frameworks durchaus mal etwas Aufmerksamkeit schenken.

Um festzustellen, ob der Browser native Promises unterstützt, genügt übrigens eine einfache „if“-Abfrage.

if (window.Promise) {
  …
}

Links zum Beitrag

  • ES6-Promise (Polyfill)
  • Promise.js
  • Q

(dpe)

Wie hilfreich war dieser Beitrag?

Klicke auf die Sterne um zu bewerten!

Durchschnittliche Bewertung 0 / 5. Anzahl Bewertungen: 0

Denis Potschien

Denis Potschien

Denis Potschien ist seit 2005 freiberuflich als Kommunikationsdesigner tätig, seit Anfang 2010 im Kreativkonsulat in Iserlohn, einem Büro für Gestaltung und Kommunikation. Dort betreut er kleine und mittelständische Unternehmen ebenso wie kommunale Körperschaften und Organisationen aus Südwestfalen und dem Ruhrgebiet. Als Webdesigner und -entwickler gehören HTML5 und CSS3 zu seinen Kernthemen, weshalb er dazu 2013 ein Buch geschrieben hat. „Pure HTML5 und CSS3“ richtet sich an alle, die Vorkenntnisse haben, sich aber bisher mit HTML5 und CSS3 nicht oder nur am Rande beschäftigt haben.

Agenturpartner

Philipp Pistis – WordPress Agentur

Prittriching

Online Solutions Group

München

Chris Hortsch Webdesign

Berlin

WeDeSu Online-Agentur

Speyer

WPSteinheisser Photography

Ludwigsburg

Alle Agenturpartner

Jobs

Texter / Junior Content Marketing Manager

Innsbruck

API Developer für die TelemaxX Cloud

Karlsruhe

SEA Manager in München

München

Assistent/in der Geschäfts­führung

Innsbruck

Google Ads Kampagnen­betreuer

Salzburg

Zum richtigen Job

Newsletter

Tipps, Tricks, Ratgeber. Unser Newsletter: Jeden Dienstag frisch gedruckt in Deinem Mail-Postfach.

Lust auf mehr? Wir empfehlen folgende Artikel:

Grav CMS: Blitzschnell, einfach und modern

Grav CMS ist eines der interessantesten neuen Content Management Systeme am Markt. Es geht einen völlig anderen Weg als bisher bekannte Ansätze und kommt sehr

 →   

Du lernst nie aus: 20+ internationale Online-Schulungsangebote

Glücklicherweise sind die Zeiten vorbei, in denen sich Wissen hinter den Mauern altehrwürdiger Schulen oder in den Tiefen riesiger Bibliotheken verschanzte. Weite Teile der Weltbevölkerung

 →   

Atomic Design: So gestaltest du deine Website modular

Begrifflichkeiten im Webdesign sind häufig nicht viel mehr als Worthülsen. Der Begriff „Atomic Design” darf zu diesen Hülsen gezählt werden. Denn er dient nur seinem

 →   

Eine Antwort zu „JavaScript: mit nativen Promises auf Callback-Verschachtelungen verzichten“
— was ist Deine Meinung?

  1. max sagt:
    14. Mai 2015 um 1:58 Uhr

    Aktuelle Browser Unterstützung?

    Antworten

Schreibe einen Kommentar Antworten abbrechen

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Dr. Web Logo weiss.

Pionier für Digitale Transformation. Seit 1997. ✅  Wissen, Tipps, Ratgeber, Dienstleister: Wir bringen wir die digitale Transformation von Unternehmen praxisnah voran.

Share on facebook
Share on twitter
Share on linkedin
Share on xing
Share on whatsapp
Share on email

Wissen finden

  • Dr. Web Autoren
  • Amazon SEO
  • Content Marketing
  • CMS
  • CSS
  • Digitalisierung
  • E-Commerce
  • Freelancer
  • Jobs & Karriere
  • Online-Marketing
  • SEO
  • UX Design
  • Webdesign
  • Website erstellen
  • WordPress
  • WooCommerce
Menü
  • Dr. Web Autoren
  • Amazon SEO
  • Content Marketing
  • CMS
  • CSS
  • Digitalisierung
  • E-Commerce
  • Freelancer
  • Jobs & Karriere
  • Online-Marketing
  • SEO
  • UX Design
  • Webdesign
  • Website erstellen
  • WordPress
  • WooCommerce

Rechtliches

  • Datenschutzerklärung
  • Geschäftsbedingungen (AGB)
  • Impressum
  • Kontakt
  • Nach oben ↑
Menü
  • Datenschutzerklärung
  • Geschäftsbedingungen (AGB)
  • Impressum
  • Kontakt
  • Nach oben ↑

Für Agenturen & Unternehmer

  • Als Agentur eintragen
  • Beste Agenturen finden
  • Städte: von A bis Z.
  • Agenturen in Augsburg
  • Agenturen in Basel
  • Agenturen in Berlin
  • Agenturen in Bochum
  • Agenturen in Bonn
  • Agenturen in Bremen
  • Agenturen in Dortmund
  • Agenturen in Dresden
  • Agenturen in Duisburg
  • Agenturen in Düsseldorf
  • Agenturen in Essen
  • Agenturen in Frankfurt am Main
  • Agenturen in Freiburg
  • Agenturen in Hamburg
  • Agenturen in Hannover
  • Agenturen in Innsbruck
  • Agenturen in Karlsruhe
  • Agenturen in Köln
  • Agenturen in Leipzig
  • Agenturen in München
  • Agenturen in Münster
  • Agenturen in Nürnberg
  • Agenturen in Offenbach am Main
  • Agenturen in Regensburg
  • Agenturen in Salzburg
  • Agenturen in Stuttgart
  • Agenturen in Wien
  • Agenturen in Zürich
  • Digitalagentur finden
  • Webdesign-Agentur finden
  • Werbeagentur finden
Menü
  • Als Agentur eintragen
  • Beste Agenturen finden
  • Städte: von A bis Z.
  • Agenturen in Augsburg
  • Agenturen in Basel
  • Agenturen in Berlin
  • Agenturen in Bochum
  • Agenturen in Bonn
  • Agenturen in Bremen
  • Agenturen in Dortmund
  • Agenturen in Dresden
  • Agenturen in Duisburg
  • Agenturen in Düsseldorf
  • Agenturen in Essen
  • Agenturen in Frankfurt am Main
  • Agenturen in Freiburg
  • Agenturen in Hamburg
  • Agenturen in Hannover
  • Agenturen in Innsbruck
  • Agenturen in Karlsruhe
  • Agenturen in Köln
  • Agenturen in Leipzig
  • Agenturen in München
  • Agenturen in Münster
  • Agenturen in Nürnberg
  • Agenturen in Offenbach am Main
  • Agenturen in Regensburg
  • Agenturen in Salzburg
  • Agenturen in Stuttgart
  • Agenturen in Wien
  • Agenturen in Zürich
  • Digitalagentur finden
  • Webdesign-Agentur finden
  • Werbeagentur finden
Das große Dr. Web Icon-Set: 970+ Icons, im SVG-Format​

Lade Dir jetzt das Icon-Set
kostenlos herunter ↓

Über 970 Dr. Web-Icons, kostenlos.
Danke nein, ist nichts für mich.
Invalid email address
Vielen Dank! Bitte schau noch in Dein Postfach und bestätige die Anmeldung.