{"id":36774,"date":"2019-10-31T22:13:44","date_gmt":"2019-10-31T19:13:44","guid":{"rendered":"https:\/\/prohoster.info\/blog\/asinhronnoe-programmirovanie-v-javascript-callback-promise-rxjs\/"},"modified":"2019-10-31T22:13:44","modified_gmt":"2019-10-31T19:13:44","slug":"asinhronnoe-programmirovanie-v-javascript-callback-promise-rxjs","status":"publish","type":"post","link":"https:\/\/prohoster.info\/de\/blog\/news\/asinhronnoe-programmirovanie-v-javascript-callback-promise-rxjs","title":{"rendered":"Asynchrone Programmierung in JavaScript. ( Callback, Promise, RxJs )","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Hallo zusammen. Hier ist Sergey Omelnitsky. Vor kurzem habe ich einen Livestream zum reaktiven Programmieren gehalten, in dem ich \u00fcber Asynchronit\u00e4t in JavaScript gesprochen habe. Heute m\u00f6chte ich dieses Material zusammenfassen. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynchrone Programmierung in JavaScript. ( Callback, Promise, RxJs )\" src=\"\/wp-content\/uploads\/2019\/08\/11acf6af8328d3deb6f0ce48e813efb7.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Aber bevor wir mit dem Hauptmaterial beginnen, m\u00fcssen wir eine Einf\u00fchrung machen. Lass uns also mit Definitionen beginnen: Was ist ein Stack und eine Queue?<br \/>\n<strong>Stack <\/strong>\u2014 das ist eine Sammlung, deren Elemente nach dem Prinzip \u201eLast In, First Out\u201c (LIFO) verarbeitet werden.<br \/>\n<strong>Warteschlange <\/strong>\u2014 das ist eine Sammlung, deren Elemente nach dem Prinzip \u201eFirst In, First Out\u201c (FIFO) verarbeitet werden.<\/p>\n<p><\/p>\n<p>Okay, lass uns fortfahren. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynchrone Programmierung in JavaScript. ( Callback, Promise, RxJs )\" src=\"\/wp-content\/uploads\/2019\/08\/a7d64d1c74f37b463869dd57b96c9d0e.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>JavaScript ist eine einzeln laufende Programmiersprache. Das bedeutet, dass es nur einen Ausf\u00fchrungsstrang und einen Stack gibt, in den Funktionen zur Ausf\u00fchrung eingereiht werden. Folglich kann JavaScript zu einem bestimmten Zeitpunkt nur eine Operation ausf\u00fchren, w\u00e4hrend andere Operationen im Stack warten m\u00fcssen, bis sie aufgerufen werden. <\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<p><strong>Call Stack<\/strong> \u2014 das ist eine Datenstruktur, die vereinfacht gesagt Informationen dar\u00fcber speichert, wo wir uns im Programm befinden. Wenn wir in eine Funktion eintreten, f\u00fcgen wir einen Eintrag daf\u00fcr an die Spitze des Stacks hinzu. Wenn wir aus der Funktion zur\u00fcckkehren, ziehen wir das oberste Element aus dem Stack und gelangen dorthin, wo wir diese Funktion aufgerufen haben. Das ist alles, was der Stack kann. Und jetzt eine sehr interessante Frage: Wie funktioniert dann die Asynchronit\u00e4t in JavaScript?<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynchrone Programmierung in JavaScript. ( Callback, Promise, RxJs )\" src=\"\/wp-content\/uploads\/2019\/08\/a29fd1dd3de06fb203c7dd14bda30548.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Tats\u00e4chlich gibt es neben dem Stack in Browsern eine spezielle Queue f\u00fcr die Arbeit mit dem sogenannten WebAPI. Funktionen aus dieser Queue werden der Reihe nach erst nach vollst\u00e4ndiger Leerung des Stacks ausgef\u00fchrt. Erst dann werden sie von der Queue in den Stack zur Ausf\u00fchrung verschoben. Wenn sich zu diesem Zeitpunkt mindestens ein Element im Stack befindet, k\u00f6nnen sie nicht in den Stack gelangen. Genau wegen dieser Tatsache ist der Aufruf von Funktionen mit einem Timeout oft nicht zeitgenau, da die Funktion nicht in den Stack gelangen kann, solange dieser voll ist. <\/p>\n<p><\/p>\n<p>Betrachten wir das folgende Beispiel und schauen uns seine schrittweise \u201eAusf\u00fchrung\u201c an. Lass uns auch untersuchen, was dabei im System passiert.<\/p>\n<p><\/p>\n<pre><code class=\"javascript\">console.log('Hi);\nsetTimeout(function cb1() {\n    console.log('cb1');\n}, 5000);\nconsole.log('Bye');<\/code><\/pre>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynchrone Programmierung in JavaScript. ( Callback, Promise, RxJs )\" src=\"\/wp-content\/uploads\/2019\/08\/379423fca95fb28b2124be03dfd15739.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>1) Bis jetzt passiert nichts. Die Konsole des Browsers ist leer, der Call Stack ist leer.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynchrone Programmierung in JavaScript. ( Callback, Promise, RxJs )\" src=\"\/wp-content\/uploads\/2019\/08\/4a16bbc23bade54ae0b02d81d5f6a581.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>2) Dann wird der Befehl console.log('Hi') zum Aufrufestack hinzugef\u00fcgt.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynchrone Programmierung in JavaScript. ( Callback, Promise, RxJs )\" src=\"\/wp-content\/uploads\/2019\/08\/a1845af23fd7dedebf94afc168f1f13f.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>3) Und er wird ausgef\u00fchrt.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynchrone Programmierung in JavaScript. ( Callback, Promise, RxJs )\" src=\"\/wp-content\/uploads\/2019\/08\/57397b53386018b662f3a79a6d4d60fb.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>4) Dann wird console.log('Hi') aus dem Aufrufestack entfernt.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynchrone Programmierung in JavaScript. ( Callback, Promise, RxJs )\" src=\"\/wp-content\/uploads\/2019\/08\/7cb2b32be8807ecf39d2f38683ccd435.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>5) Jetzt gehen wir zum Befehl setTimeout(function cb1() {\u2026 }) \u00fcber. Er wird zum Aufrufstack hinzugef\u00fcgt.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynchrone Programmierung in JavaScript. ( Callback, Promise, RxJs )\" src=\"\/wp-content\/uploads\/2019\/08\/99c0724994e3390d009577852b451beb.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>6) Der Befehl setTimeout(function cb1() {\u2026 }) wird ausgef\u00fchrt. Der Browser erstellt einen Timer, der Teil der Web-API ist. Er wird den Countdown starten.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynchrone Programmierung in JavaScript. ( Callback, Promise, RxJs )\" src=\"\/wp-content\/uploads\/2019\/08\/99086cdeafd83c5fe72e92c4a9f9b738.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>7) Der Befehl setTimeout(function cb1() {\u2026 }) hat seine Arbeit beendet und wird aus dem Aufrufstack entfernt.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynchrone Programmierung in JavaScript. ( Callback, Promise, RxJs )\" src=\"\/wp-content\/uploads\/2019\/08\/24ac12b1b6cfbff780ece9e9a7acd7c7.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>8) Der Befehl console.log('Bye') wird zum Aufrufestack hinzugef\u00fcgt.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynchrone Programmierung in JavaScript. ( Callback, Promise, RxJs )\" src=\"\/wp-content\/uploads\/2019\/08\/6ccad0ad8eebf05e870a409766d38766.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>9) Der Befehl console.log('Bye') wird ausgef\u00fchrt.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynchrone Programmierung in JavaScript. ( Callback, Promise, RxJs )\" src=\"\/wp-content\/uploads\/2019\/08\/09e4e380eb873fb23bea550f3ffb21f7.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>10) Der Befehl console.log('Bye') wird aus dem Aufrufestack entfernt.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynchrone Programmierung in JavaScript. ( Callback, Promise, RxJs )\" src=\"\/wp-content\/uploads\/2019\/08\/357bfb372361310681ba7bb1860d90d7.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>11) Nachdem mindestens 5000 ms vergangen sind, beendet der Timer seine Arbeit und f\u00fcgt den Callback cb1 in die Callback-Warteschlange ein.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynchrone Programmierung in JavaScript. ( Callback, Promise, RxJs )\" src=\"\/wp-content\/uploads\/2019\/08\/8170e8ff5d3d0c56c0091658370c25cc.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>12) Der Event Loop nimmt die Funktion cb1 aus der Callback-Warteschlange und f\u00fcgt sie in den Aufrufstack ein.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynchrone Programmierung in JavaScript. ( Callback, Promise, RxJs )\" src=\"\/wp-content\/uploads\/2019\/08\/d858a54e82bc32d84f854610db462bc1.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>13) Die Funktion cb1 wird ausgef\u00fchrt und f\u00fcgt console.log('cb1') dem Aufrufestack hinzu.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynchrone Programmierung in JavaScript. ( Callback, Promise, RxJs )\" src=\"\/wp-content\/uploads\/2019\/08\/6ca8e016389904eec57035e64d57a157.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>14) Der Befehl console.log('cb1') wird ausgef\u00fchrt.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynchrone Programmierung in JavaScript. ( Callback, Promise, RxJs )\" src=\"\/wp-content\/uploads\/2019\/08\/0caa645a90ac1fca5fb8a76569494d48.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>15) Der Befehl console.log('cb1') wird aus dem Aufrufestack entfernt.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynchrone Programmierung in JavaScript. ( Callback, Promise, RxJs )\" src=\"\/wp-content\/uploads\/2019\/08\/aeb838fe8df3f6e3f8603a4207a6e193.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>16) Die Funktion cb1 wird aus dem Aufrufstack entfernt.<\/p>\n<p><\/p>\n<p>Sehen wir uns ein Beispiel in der Dynamik an:<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynchrone Programmierung in JavaScript. ( Callback, Promise, RxJs )\" src=\"\/wp-content\/uploads\/2019\/08\/3836d9df513afee374f498720990e39f.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Nun haben wir gesehen, wie Asynchronit\u00e4t in JavaScript implementiert ist. Lassen Sie uns nun kurz \u00fcber die Entwicklung asynchronen Codes sprechen.<\/p>\n<p><\/p>\n<h2 id=\"evolyuciya-asinhronnogo-koda\">Die Entwicklung asynchronen Codes.<\/h2>\n<p><\/p>\n<pre><code class=\"javascript\">a(function (resultsFromA) {\n    b(resultsFromA, function (resultsFromB) {\n        c(resultsFromB, function (resultsFromC) {\n            d(resultsFromC, function (resultsFromD) {\n                e(resultsFromD, function (resultsFromE) {\n                    f(resultsFromE, function (resultsFromF) {\n                        console.log(resultsFromF);\n                    })\n                })\n            })\n        })\n    })\n});<\/code><\/pre>\n<p><\/p>\n<p>Asynchrones Programmieren, wie wir es in JavaScript kennen, kann nur durch Funktionen umgesetzt werden. Diese k\u00f6nnen wie jede andere Variable an andere Funktionen \u00fcbergeben werden. So entstanden Callbacks. Und das macht Spa\u00df, solange es nicht in Traurigkeit und Kummer umschl\u00e4gt. Warum? Weil:<\/p>\n<p><\/p>\n<ul>\n<li>Mit wachsender Komplexit\u00e4t des Codes verwandelt sich das Projekt schnell in schwer verst\u00e4ndliche mehrfach geschachtelte Bl\u00f6cke \u2013 \u201eCallback-H\u00f6lle\u201c.<\/li>\n<li>Fehlerbehandlung kann leicht \u00fcbersehen werden.<\/li>\n<li>Die Ausdr\u00fccke k\u00f6nnen nicht mit return zur\u00fcckgegeben werden.<\/li>\n<\/ul>\n<p><\/p>\n<p>Mit dem Erscheinen von Promise wurde die Situation etwas besser.<\/p>\n<p><\/p>\n<pre><code class=\"javascript\">new Promise(function(resolve, reject) {\n    setTimeout(() =&gt; resolve(1), 2000);\n\n}).then((result) =&gt; {\n    alert(result);\n    return result + 2;\n\n}).then((result) =&gt; {\n    throw new Error('FAILED HERE');\n    alert(result);\n    return result + 2;\n\n}).then((result) =&gt; {\n    alert(result);\n    return result + 2;\n\n}).catch((e) =&gt; {\n    console.log('error: ', e);\n});<\/code><\/pre>\n<p><\/p>\n<ul>\n<li>Es entstanden Ketten von Promises, was die Lesbarkeit des Codes verbesserte.<\/li>\n<li>Eine separate Methode zur Fehlerbehandlung wurde eingef\u00fchrt.<\/li>\n<li>Es wurde die M\u00f6glichkeit der parallelen Ausf\u00fchrung mit Promise.all geschaffen.<\/li>\n<li>Wir k\u00f6nnen die eingebettete Asynchronit\u00e4t mit async\/await l\u00f6sen.<\/li>\n<\/ul>\n<p><\/p>\n<p>Aber ein Promise hat seine Beschr\u00e4nkungen. Zum Beispiel kann ein Promise ohne viel Aufwand nicht abgebrochen werden, und das Wichtigste ist \u2014 es funktioniert mit einem einzigen Wert.<\/p>\n<p><\/p>\n<p>Nun, wir sind also sanft zum reaktiven Programmieren \u00fcbergegangen. M\u00fcde? Nun, zum Gl\u00fcck kann man sich einen Tee machen, nachdenken und dann weiterlesen. Ich fahre fort.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynchrone Programmierung in JavaScript. ( Callback, Promise, RxJs )\" src=\"\/wp-content\/uploads\/2019\/08\/48409ec625d57fec171214c1de332c85.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p><strong>Reaktives Programmieren<\/strong>\u200a\u2014\u200aeine Programmierparadigma, die sich auf Datenstr\u00f6me und das Verbreiten von \u00c4nderungen konzentriert. Lassen Sie uns genauer betrachten, was ein Datenstrom ist.<\/p>\n<p><\/p>\n<pre><code class=\"javascript\">\/\/ \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\nconst input = ducument.querySelector('input');\n\nconst eventsArray = [];\n\n\/\/ \u041f\u0443\u0448\u0438\u043c \u043a\u0430\u0436\u0434\u043e\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u0432 \u043c\u0430\u0441\u0441\u0438\u0432 eventsArray\ninput.addEventListener('keyup',\n    event =&gt; eventsArray.push(event)\n);<\/code><\/pre>\n<p><\/p>\n<p>Stellen wir uns vor, wir haben ein Eingabefeld. Wir erstellen ein Array und bei jedem keyup-Ereignis des Inputs werden wir das Ereignis in unserem Array speichern. Dabei sollte erw\u00e4hnt werden, dass unser Array nach Zeit sortiert ist, d.h. der Index sp\u00e4terer Ereignisse ist gr\u00f6\u00dfer als der Index fr\u00fcherer Ereignisse. Ein solches Array stellt ein vereinfachtes Modell eines Datenstroms dar, aber es ist noch kein Strom. Damit man dieses Array als Strom bezeichnen kann, muss es in der Lage sein, den Abonnenten mitzuteilen, dass neue Daten eingegeben wurden. So sind wir zur Definition eines Stroms gekommen.<\/p>\n<p><\/p>\n<h3 id=\"potok-dannyh\">Datenfluss<\/h3>\n<p><\/p>\n<pre><code class=\"javascript\">const { interval1 } = Rx;\nconst { take } = RxOperators;\n\ninterval(1000).pipe(\n    take(4)\n)<\/code><\/pre>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynchrone Programmierung in JavaScript. ( Callback, Promise, RxJs )\" src=\"\/wp-content\/uploads\/2019\/08\/68ec447abafb6b8a323b429ed94f8252.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p><strong>Ein Strom\u200a<\/strong>\u2014\u200aist ein Array von Daten, das nach Zeit sortiert ist und mitteilen kann, dass sich die Daten ge\u00e4ndert haben. Stellen Sie sich vor, wie bequem es wird, Code zu schreiben, bei dem eine Aktion mehrere Ereignisse an verschiedenen Stellen im Code erfordert. Wir abonnieren einfach den Strom, und er sagt uns selbst, wann \u00c4nderungen stattfinden. Und das kann die Bibliothek RxJs.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynchrone Programmierung in JavaScript. ( Callback, Promise, RxJs )\" src=\"\/wp-content\/uploads\/2019\/08\/dcb1cfca8b4d8a887b63c302a7d6c06a.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p><strong>RxJS <\/strong> \u2014 ist eine Bibliothek zur Arbeit mit asynchronen und ereignisgesteuerten Programmen unter Verwendung von beobachtbaren Sequenzen. Die Bibliothek bietet den Haupttyp <em>Observable<\/em>, mehrere Hilfstypen (<em>Observer, Schedulers, Subjects<\/em>) und Operatoren zur Bearbeitung von Ereignissen wie Sammlungen (<em>map, filter, reduce, every<\/em> und \u00e4hnliches aus JavaScript Array).<\/p>\n<p><\/p>\n<p>Lassen Sie uns die grundlegenden Begriffe dieser Bibliothek kl\u00e4ren.<\/p>\n<p><\/p>\n<h3 id=\"observable-observer-producer\">Observable, Observer, Producer<\/h3>\n<p><\/p>\n<p>Observable \u2014 der erste grundlegende Typ, den wir betrachten werden. Diese Klasse enth\u00e4lt den Hauptteil der Umsetzung von RxJs. Sie ist mit dem beobachtbaren Strom verbunden, auf den man sich mit der Methode subscribe anmelden kann.<\/p>\n<p><\/p>\n<p>In Observable wird ein Hilfsmechanismus zur Erstellung von Updates implementiert, der sogenannte <em>Observer<\/em>. Die Quelle der Werte f\u00fcr den Observer wird genannt <em>Producer<\/em>. Dies kann ein Array, ein Iterator, ein Websocket, ein Ereignis usw. sein. Man kann also sagen, dass observable ein Vermittler zwischen Producer und Observer ist. <\/p>\n<p><\/p>\n<p>Observable verarbeitet drei Arten von Ereignissen f\u00fcr den Observer:<\/p>\n<p><\/p>\n<ul>\n<li>next \u2013 neue Daten<\/li>\n<li>error \u2013 ein Fehler, wenn die Sequenz aufgrund einer Ausnahme beendet wurde. Dieses Ereignis signalisiert ebenfalls das Ende der Sequenz.<\/li>\n<li>complete \u2013 ein Signal f\u00fcr das Ende der Sequenz. Das bedeutet, dass keine neuen Daten mehr verf\u00fcgbar sind.<\/li>\n<\/ul>\n<p><\/p>\n<p>Sehen wir uns eine Demo an:<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynchrone Programmierung in JavaScript. ( Callback, Promise, RxJs )\" src=\"\/wp-content\/uploads\/2019\/08\/c5bcd2af0f18b6de3ab0dbc20db595d1.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Zu Beginn verarbeiten wir die Werte 1, 2, 3, und nach 1 Sekunde erhalten wir 4 und beenden unseren Stream.<\/p>\n<p>\n<b class=\"spoiler_title\">Gedanken laut<\/b><\/p>\n<p>Und hier wurde mir klar, dass es interessanter war, dar\u00fcber zu erz\u00e4hlen als es aufzuschreiben. \ud83d\ude00 <\/p>\n<p><\/p>\n<h3 id=\"subscription\">Subscription<\/h3>\n<p><\/p>\n<p>Wenn wir uns f\u00fcr einen Stream anmelden, erstellen wir eine neue Klasse <strong>subscription<\/strong>, die es uns erm\u00f6glicht, die Anmeldung mit der Methode <em>unsubscribe<\/em>zu widerrufen. Wir k\u00f6nnen auch Abonnements mit der Methode <em>add<\/em>gruppieren. Und es ist logisch, dass wir Streams mit <em>remove<\/em>aufteilen k\u00f6nnen. Die Methoden add und remove nehmen eine andere Subscription als Eingabe. Ich m\u00f6chte hervorheben, dass wir bei einer Abmeldung auch von allen untergeordneten Abonnements abgemeldet werden, als ob wir bei ihnen die Methode unsubscribe aufgerufen h\u00e4tten. Lassen Sie uns fortfahren.<\/p>\n<p><\/p>\n<h3 id=\"vidy-potokov\">Arten von Streams<\/h3>\n<p><\/p>\n<table>\n<thead>\n<tr>\n<th>HOT<\/th>\n<th>COLD<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Producer wird au\u00dferhalb von observable erstellt<\/td>\n<td>Producer wird innerhalb von observable erstellt<\/td>\n<\/tr>\n<tr>\n<td>Daten werden zum Zeitpunkt der Erstellung von observable \u00fcbergeben<\/td>\n<td>Daten werden zum Zeitpunkt der Anmeldung \u00fcbermittelt<\/td>\n<\/tr>\n<tr>\n<td>Zus\u00e4tzliche Logik ist erforderlich, um sich abzumelden<\/td>\n<td>Der Stream endet von selbst<\/td>\n<\/tr>\n<tr>\n<td>Verwendet eine Eins-zu-viele-Beziehung<\/td>\n<td>Verwendet eine Eins-zu-eins-Beziehung<\/td>\n<\/tr>\n<tr>\n<td>Alle Abonnements haben denselben Wert<\/td>\n<td>Abonnements sind unabh\u00e4ngig<\/td>\n<\/tr>\n<tr>\n<td>Daten k\u00f6nnen verloren gehen, wenn kein Abonnement besteht<\/td>\n<td>Gibt alle Werte des Streams f\u00fcr ein neues Abonnement erneut aus<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><\/p>\n<p>Wenn ich eine Analogie ziehen m\u00fcsste, w\u00fcrde ich den hei\u00dfen Stream mit einem Film im Kino vergleichen. Zu welchem Zeitpunkt du kommst, beginnt auch dein Sehen. Den kalten Stream w\u00fcrde ich mit einem Anruf beim technischen Support vergleichen. Jeder Anrufer h\u00f6rt die Ansage des Anrufbeantworters von Anfang bis Ende, aber du kannst das Gespr\u00e4ch mit der Methode unsubscribe beenden.<\/p>\n<p><\/p>\n<p>Ich m\u00f6chte darauf hinweisen, dass es auch sogenannte warmen Str\u00f6me gibt (diese Definition habe ich sehr selten gesehen, und zwar nur in ausl\u00e4ndischen Gemeinschaften) \u2014 es handelt sich um einen Strom, der sich von einem kalten Strom in einen hei\u00dfen verwandelt. Die Frage stellt sich \u2014 wo zu verwenden)) Ich gebe ein Beispiel aus der Praxis.<\/p>\n<p><\/p>\n<p>Ich arbeite mit Angular. Es verwendet aktiv RxJS. Um Daten auf dem Server zu erhalten, erwarte ich einen kalten Strom und verwende diesen Strom im Template mit asyncPipe. Wenn ich dieses Pipe mehrmals verwende, wird, bezogen auf die Definition des kalten Stroms, jede Pipe Daten vom Server anfordern, was gelinde gesagt seltsam ist. Wenn ich jedoch den kalten Strom in einen warmen umwandle, erfolgt die Anforderung nur einmal.<\/p>\n<p><\/p>\n<p>Das Verst\u00e4ndnis der Arten von Str\u00f6men ist f\u00fcr Anf\u00e4nger ziemlich komplex, aber wichtig. <\/p>\n<p><\/p>\n<h3 id=\"operators\">Operatoren<\/h3>\n<p><\/p>\n<pre><code class=\"javascript\">return this.http.get(`${environment.apiUrl}\/${this.apiUrl}\/trade_companies`)\n    .pipe(\n        tap(({ data }: TradeCompanyList) =&gt; this.companies$$.next(cloneDeep(data))),\n        map(({ data }: TradeCompanyList) =&gt; data)\n    );<\/code><\/pre>\n<p><\/p>\n<p>Operatoren bieten erweiterte M\u00f6glichkeiten zur Arbeit mit Str\u00f6men. Sie helfen, Ereignisse zu kontrollieren, die in Observable ablaufen. Wir werden ein paar der beliebtesten betrachten; detailliertere Informationen zu den Operatoren finden Sie in den Links zu n\u00fctzlichen Informationen.<\/p>\n<p><\/p>\n<p><strong>Operatoren \u2014 of<\/strong><\/p>\n<p><\/p>\n<p>Beginnen wir mit dem Hilfsoperator of. Er erstellt ein Observable basierend auf einem einfachen Wert.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynchrone Programmierung in JavaScript. ( Callback, Promise, RxJs )\" src=\"\/wp-content\/uploads\/2019\/08\/68f382447e306392b025867a9a1e88e7.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p><strong>Operatoren \u2014 filter<\/strong><\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynchrone Programmierung in JavaScript. ( Callback, Promise, RxJs )\" src=\"\/wp-content\/uploads\/2019\/08\/24ac65fdb5ccc7f6301b3dfe49f1e804.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Der Filteroperator filtert, wie man dem Namen entnehmen kann, das Signal des Stroms. Wenn der Operator true zur\u00fcckgibt, wird das Signal weitergeleitet.<\/p>\n<p><\/p>\n<p><strong>Operatoren \u2014 take<\/strong><\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynchrone Programmierung in JavaScript. ( Callback, Promise, RxJs )\" src=\"\/wp-content\/uploads\/2019\/08\/b3e7a2a2e03038d6fc250247ff4496a2.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>take \u2014 Nimmt die Anzahl der Emissionen, nach denen der Strom beendet wird.<\/p>\n<p><\/p>\n<p><strong>Operatoren \u2014 debounceTime<\/strong><\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynchrone Programmierung in JavaScript. ( Callback, Promise, RxJs )\" src=\"\/wp-content\/uploads\/2019\/08\/add686e546a0b6169c38fb3b457da928.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>debounceTime \u2014 verwirft emittierte Werte, die in den angegebenen Zeitrahmen zwischen den Ausgaben fallen. Nach Ablauf des Zeitintervalls wird der letzte Wert emittiert.<\/p>\n<p><\/p>\n<pre><code class=\"javascript\">const { Observable } = Rx;\nconst { debounceTime, take } = RxOperators;\n\nObservable.create((observer) =&gt; {\n  let i = 1;\n  observer.next(i++);\n  \/\/ Emit it every 1000ms\n  setInterval(() =&gt; {\n    observer.next(i++)\n  }, 1000);\n\n  \/\/ Emit it every 1500ms\n  setInterval(() =&gt; {\n    observer.next(i++)\n  }, 1500);\n}).pipe(\n  debounceTime(700), \/\/ Warten Sie 700ms auf Werte, bevor Sie sie verarbeiten\n  take(3)\n);  <\/code><\/pre>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynchrone Programmierung in JavaScript. ( Callback, Promise, RxJs )\" src=\"\/wp-content\/uploads\/2019\/08\/dbb690d6fea6c43c1f0a2bdabea57934.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p><strong>Operatoren \u2014 takeWhile<\/strong><\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynchrone Programmierung in JavaScript. ( Callback, Promise, RxJs )\" src=\"\/wp-content\/uploads\/2019\/08\/120d9fe6ddf5a60ddffc8742989b27ff.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Emittiert Werte, solange takeWhile nicht false zur\u00fcckgibt, danach wird vom Strom abgemeldet.<\/p>\n<p><\/p>\n<pre><code class=\"javascript\">const { Observable } = Rx;\nconst { debounceTime, takeWhile } = RxOperators;\n\nObservable.create((observer) =&gt; {\n  let i = 1;\n  observer.next(i++);\n  \/\/ Emit value every 1000ms\n  setInterval(() =&gt; {\n    observer.next(i++)\n  }, 1000);\n}).pipe(\n  takeWhile(producer =&gt; producer &lt; 5)\n);  <\/code><\/pre>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynchrone Programmierung in JavaScript. ( Callback, Promise, RxJs )\" src=\"\/wp-content\/uploads\/2019\/08\/d2910d1bf9fab228acc9241fdbad3d4a.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p><strong>Operatoren \u2014 combineLatest<\/strong><\/p>\n<p><\/p>\n<p>Der kombinierte Operator combineLatest \u00e4hnelt promise.all. Er kombiniert mehrere Streams in einem. Nachdem jeder Stream mindestens einmal einen Wert emittiert hat, erhalten wir die letzten Werte von jedem in Form eines Arrays. Nach jedem Emit eines der kombinierten Streams werden neue Werte zur\u00fcckgegeben.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynchrone Programmierung in JavaScript. ( Callback, Promise, RxJs )\" src=\"\/wp-content\/uploads\/2019\/08\/c39bc0a8a736ed30ad147055110bbf55.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<pre><code class=\"javascript\">const { combineLatest, Observable } = Rx;\nconst { take } = RxOperators;\n\nconst observer_1 = Observable.create((observer) =&gt; {\n  let i = 1;\n  \/\/ Emit value every 1000ms\n  setInterval(() =&gt; {\n    observer.next('a: ' + i++);\n  }, 1000);\n});\n\nconst observer_2 = Observable.create((observer) =&gt; {\n  let i = 1;\n  \/\/ Emit value every 750ms\n  setInterval(() =&gt; {\n    observer.next('b: ' + i++);\n  }, 750);\n});\n\ncombineLatest(observer_1, observer_2).pipe(take(5));<\/code><\/pre>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynchrone Programmierung in JavaScript. ( Callback, Promise, RxJs )\" src=\"\/wp-content\/uploads\/2019\/08\/7fc35461f446987ef81302ff7c2ed5a8.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p><strong>Operatoren \u2014 zip<\/strong><\/p>\n<p><\/p>\n<p>Zip erwartet einen Wert aus jedem Stream und bildet ein Array auf der Grundlage dieser Werte. Wenn aus einem Stream kein Wert empfangen wird, wird die Gruppe nicht gebildet.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynchrone Programmierung in JavaScript. ( Callback, Promise, RxJs )\" src=\"\/wp-content\/uploads\/2019\/08\/0be5ee0d2ec56bd2bc245b15d43d4cc1.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<pre><code class=\"javascript\">const { zip, Observable } = Rx;\nconst { take } = RxOperators;\n\nconst observer_1 = Observable.create((observer) =&gt; {\n  let i = 1;\n  \/\/ Emit value every 1000ms\n  setInterval(() =&gt; {\n    observer.next('a: ' + i++);\n  }, 1000);\n});\n\nconst observer_2 = Observable.create((observer) =&gt; {\n  let i = 1;\n  \/\/ Emit value every 750ms\n  setInterval(() =&gt; {\n    observer.next('b: ' + i++);\n  }, 750);\n});\n\nconst observer_3 = Observable.create((observer) =&gt; {\n  let i = 1;\n  \/\/ Emit value every 500ms\n  setInterval(() =&gt; {\n    observer.next('c: ' + i++);\n  }, 500);\n});\n\nzip(observer_1, observer_2, observer_3).pipe(take(5));<\/code><\/pre>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynchrone Programmierung in JavaScript. ( Callback, Promise, RxJs )\" src=\"\/wp-content\/uploads\/2019\/08\/e2606bf8ea5f8a660699ebe896a27d80.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p><strong>Operatoren \u2014 forkJoin<\/strong><\/p>\n<p><\/p>\n<p>forkJoin kombiniert ebenfalls Streams, jedoch gibt er einen Wert nur aus, wenn alle Streams abgeschlossen sind (complete).<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynchrone Programmierung in JavaScript. ( Callback, Promise, RxJs )\" src=\"\/wp-content\/uploads\/2019\/08\/6c430d7eeafbc8a7c1c228ddfe0e44b5.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<pre><code class=\"javascript\">const { forkJoin, Observable } = Rx;\nconst { take } = RxOperators;\n\nconst observer_1 = Observable.create((observer) =&gt; {\n  let i = 1;\n  \/\/ Emit value every 1000ms\n  setInterval(() =&gt; {\n    observer.next('a: ' + i++);\n  }, 1000);\n}).pipe(take(3));\n\nconst observer_2 = Observable.create((observer) =&gt; {\n  let i = 1;\n  \/\/ Emit value every 750ms\n  setInterval(() =&gt; {\n    observer.next('b: ' + i++);\n  }, 750);\n}).pipe(take(5));\n\nconst observer_3 = Observable.create((observer) =&gt; {\n  let i = 1;\n  \/\/ Emit value every 500ms\n  setInterval(() =&gt; {\n    observer.next('c: ' + i++);\n  }, 500);\n}).pipe(take(4));\n\nforkJoin(observer_1, observer_2, observer_3);<\/code><\/pre>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynchrone Programmierung in JavaScript. ( Callback, Promise, RxJs )\" src=\"\/wp-content\/uploads\/2019\/08\/df110efc7ece46fc1d8da2d7693f75bb.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p><strong>Operatoren \u2014 map<\/strong><\/p>\n<p><\/p>\n<p>Der Transformationsoperator map wandelt den Wert des Emittierten in einen neuen um. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynchrone Programmierung in JavaScript. ( Callback, Promise, RxJs )\" src=\"\/wp-content\/uploads\/2019\/08\/2196ff9f82dd7aaeb00ab76475176d32.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<pre><code class=\"javascript\">const { Observable } = Rx;\nconst { take, map } = RxOperators;\n\nObservable.create((observer) =&gt; {\n  let i = 1;\n  \/\/ Emit value every 1000ms\n  setInterval(() =&gt; {\n    observer.next(i++);\n  }, 1000);\n}).pipe(\n  map(x =&gt; x * 10),\n  take(3)\n);\n<\/code><\/pre>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynchrone Programmierung in JavaScript. ( Callback, Promise, RxJs )\" src=\"\/wp-content\/uploads\/2019\/08\/4e4ff3e2eb4acf69f16559c711a2e666.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p><strong>Operatoren \u2013 share, tap<\/strong><\/p>\n<p><\/p>\n<p>Der tap-Operator erm\u00f6glicht Nebenwirkungen, das hei\u00dft, Aktionen, die keinen Einfluss auf die Reihenfolge haben.<\/p>\n<p><\/p>\n<p>Der Utility-Operator Share kann aus einem kalten Stream einen hei\u00dfen machen. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynchrone Programmierung in JavaScript. ( Callback, Promise, RxJs )\" src=\"\/wp-content\/uploads\/2019\/08\/c46e96420ed78d197ceef829ff74c82d.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Wir sind mit den Operatoren fertig. Lassen Sie uns zum Subject \u00fcbergehen.<\/p>\n<p>\n<b class=\"spoiler_title\">Gedanken laut<\/b><\/p>\n<p>Und hier habe ich eine Tasse Tee getrunken. Diese Beispiele haben mich m\u00fcde gemacht \ud83d\ude00<\/p>\n<p><\/p>\n<h2 id=\"semeystvo-subject-ov\">Familie der Subjects<\/h2>\n<p><\/p>\n<p>Die Familie der Subjects ist ein anschauliches Beispiel f\u00fcr hei\u00dfe Streams. Diese Klassen sind eine Art Hybrid, die gleichzeitig als Observable und Observer fungieren. Da das Subject ein hei\u00dfer Stream ist, muss man sich von ihm abmelden. Die Hauptmethoden sind:<\/p>\n<p><\/p>\n<ul>\n<li>next \u2013 \u00dcbermittlung neuer Daten an den Stream<\/li>\n<li>error \u2013 Fehler und Beendigung des Streams<\/li>\n<li>complete \u2013 Beendigung des Streams<\/li>\n<li>subscribe \u2013 f\u00fcr den Stream anmelden<\/li>\n<li>unsubscribe \u2013 vom Stream abmelden<\/li>\n<li>asObservable \u2013 in einen Observer umwandeln<\/li>\n<li>toPromise \u2013 in ein Promise umwandeln<\/li>\n<\/ul>\n<p><\/p>\n<p>Es gibt 4 bis 5 Arten von Subjects. <\/p>\n<p>\n<b class=\"spoiler_title\">Gedanken laut<\/b><\/p>\n<p>Ich habe 4 in dem Stream gesagt, aber es scheint, dass sie noch einen hinzugef\u00fcgt haben. Wie man so sagt: Lebe und lerne.<\/p>\n<p><\/p>\n<p>Einfaches Subject <code>new Subject()<\/code>\u2013 die einfachste Art von Subjects. Wird ohne Parameter erstellt. Gibt nur Werte weiter, die nach der Anmeldung empfangen wurden.<\/p>\n<p><\/p>\n<p>BehaviorSubject <code>new BehaviorSubject(defaultData&lt;T&gt;)<\/code> \u2013 meiner Meinung nach die am weitesten verbreitete Art von Subjects. Nimmt einen Standardwert als Eingabe an. Speichert immer die Daten des letzten Emits, die bei der Anmeldung \u00fcbermittelt werden. Diese Klasse hat auch eine n\u00fctzliche Methode value, die den aktuellen Wert des Streams zur\u00fcckgibt.<\/p>\n<p><\/p>\n<p>ReplaySubject <code>new ReplaySubject(bufferSize?: number, windowTime?: number)<\/code> \u2013 Kann optional als ersten Parameter die Gr\u00f6\u00dfe des Puffers von Werten annehmen, die er speichern wird, und als zweiten die Zeit, in der wir \u00c4nderungen ben\u00f6tigen.<\/p>\n<p><\/p>\n<p>AsyncSubject <code>new AsyncSubject()<\/code> \u2013 Bei der Anmeldung passiert nichts, und der Wert wird nur bei complete zur\u00fcckgegeben. Nur der letzte Wert des Streams wird zur\u00fcckgegeben.<\/p>\n<p><\/p>\n<p>WebSocketSubject <code>new WebSocketSubject(urlConfigOrSource: string | WebSocketSubjectConfig&lt;T&gt; | Observable&lt;T&gt;, destination?: Observer&lt;T&gt;)<\/code> \u2013 Dar\u00fcber schweigt die Dokumentation, und ich sehe ihn zum ersten Mal. Wer wei\u00df, was er macht, schreibt bitte, wir erg\u00e4nzen das.<\/p>\n<p><\/p>\n<p>Puh. So, das haben wir alles besprochen, was ich heute erz\u00e4hlen wollte. Ich hoffe, diese Informationen waren n\u00fctzlich. Man kann sich eigenst\u00e4ndig mit der Literatur\u00fcbersicht im Tab n\u00fctzliche Informationen vertraut machen.<\/p>\n<p><\/p>\n<h2 id=\"poleznaya-informaciya\">N\u00fctzliche Informationen<\/h2>\n<p><\/p>\n<ul>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/vk.com\/frontend_practice?w=wall-182297870_931\">https:\/\/vk.com\/frontend_practice?w=wall-182297870_931<\/a><\/noindex> \u2013 Link zum Stream<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/ruvds\/blog\/337042\/\">https:\/\/habr.com\/ru\/company\/ruvds\/blog\/337042\/<\/a><\/noindex> \u2013 Wie JS funktioniert: \u00dcberblick \u00fcber die Engine, Ausf\u00fchrungsmechanismen, Aufrufstapel<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/ruvds\/blog\/340508\/\">https:\/\/habr.com\/ru\/company\/ruvds\/blog\/340508<\/a><\/noindex> \u2014 Wie JS funktioniert: Ereignisschleife, Asynchronit\u00e4t und f\u00fcnf M\u00f6glichkeiten zur Verbesserung des Codes mit async \/ await<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"http:\/\/vanilla-js.blogspot.com\/2014\/09\/event-loop-javasript.html\">http:\/\/vanilla-js.blogspot.com\/2014\/09\/event-loop-javasript.html<\/a><\/noindex> \u2014 Wie die Ereignisschleife in JavaScript funktioniert<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/tproger.ru\/translations\/asynchronous-javascript\/\">https:\/\/tproger.ru\/translations\/asynchronous-javascript\/<\/a><\/noindex> \u2014 Evolution des asynchronen JavaScript<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/ruvds\/blog\/341880\/\">https:\/\/habr.com\/ru\/company\/ruvds\/blog\/341880\/<\/a><\/noindex> \u2014 Was ist RxJS und warum ist es n\u00fctzlich, dar\u00fcber Bescheid zu wissen<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/medium.com\/ngx\/practical-use-rxjs-81aaab57045c\">https:\/\/medium.com\/ngx\/practical-use-rxjs-81aaab57045c<\/a><\/noindex> \u2014 Praktische Anwendung von RxJS<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/coursetro.com\/posts\/code\/148\/RxJS-Observables-Tutorial---Creating-&amp;-Subscribing-to-Observables\">https:\/\/coursetro.com\/posts\/code\/148\/RxJS-Observables-Tutorial&#8212;Creating-&amp;-Subscribing-to-Observables<\/a><\/noindex> \u2014 RxJS Observables Tutorial \u2014 Erstellen &amp; Abonnieren von Observables<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/slides.com\/zenabsaleem\/rxjs-hot-cold-observables#\/\">https:\/\/slides.com\/zenabsaleem\/rxjs-hot-cold-observables#\/<\/a><\/noindex> \u2014 RXJS: Hei\u00dfe und kalte Observables<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/clck.ru\/FiPgB\">https:\/\/clck.ru\/FiPgB<\/a><\/noindex> \u2014 Klassen, Funktionen zur Erstellung von Observable. Operatoren.<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/www.learnrxjs.io\/operators\/\">https:\/\/www.learnrxjs.io\/operators\/<\/a><\/noindex> \u2014 RxJS Operatoren anhand von Beispielen<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/rxjs.dev\/api\">https:\/\/rxjs.dev\/api<\/a><\/noindex> \u2014 API-Liste<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/clck.ru\/FkS8Y\">https:\/\/clck.ru\/FkS8Y<\/a><\/noindex> \u2014 Arten von Subject und Zeitpl\u00e4nen in RxJS<\/li>\n<\/ul>\n<p>Quelle: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/462355\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442. \u041d\u0430 \u0441\u0432\u044f\u0437\u0438 \u041e\u043c\u0435\u043b\u044c\u043d\u0438\u0446\u043a\u0438\u0439 \u0421\u0435\u0440\u0433\u0435\u0439. \u041d\u0435 \u0442\u0430\u043a \u0434\u0430\u0432\u043d\u043e \u044f \u0432\u0435\u043b \u0441\u0442\u0440\u0438\u043c \u043f\u043e \u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u043e\u043c\u0443 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044e, \u0433\u0434\u0435 \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u043b \u043f\u0440\u043e \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0441\u0442\u044c \u0432 JavaScript. \u0421\u0435\u0433\u043e\u0434\u043d\u044f \u044f \u0431\u044b \u0445\u043e\u0442\u0435\u043b \u0437\u0430\u043a\u043e\u043d\u0441\u043f\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u044d\u0442\u043e\u0442 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b. \u041d\u043e \u043f\u0435\u0440\u0435\u0434 \u0442\u0435\u043c \u043a\u0430\u043a \u043d\u0430\u0447\u0430\u0442\u044c \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0432\u0432\u043e\u0434\u043d\u0443\u044e. \u0418\u0442\u0430\u043a, \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043d\u0430\u0447\u043d\u0435\u043c \u0441 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0439: \u0447\u0442\u043e \u0442\u0430\u043a\u043e\u0435 \u0441\u0442\u0435\u043a \u0438 \u043e\u0447\u0435\u0440\u0435\u0434\u044c? \u0421\u0442\u0435\u043a \u2014 \u044d\u0442\u043e \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044f, \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u043a\u043e\u0442\u043e\u0440\u043e\u0439 [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":27545,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[702],"tags":[],"class_list":["post-36774","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-news"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.1.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442. \u041d\u0430 \u0441\u0432\u044f\u0437\u0438 \u041e\u043c\u0435\u043b\u044c\u043d\u0438\u0446\u043a\u0438\u0439 \u0421\u0435\u0440\u0433\u0435\u0439. \u041d\u0435 \u0442\u0430\u043a \u0434\u0430\u0432\u043d\u043e \u044f \u0432\u0435\u043b \u0441\u0442\u0440\u0438\u043c \u043f\u043e \u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u043e\u043c\u0443 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044e, \u0433\u0434\u0435 \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u043b \u043f\u0440\u043e \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0441\u0442\u044c \u0432 JavaScript. \u0421\u0435\u0433\u043e\u0434\u043d\u044f \u044f \u0431\u044b \u0445\u043e\u0442\u0435\u043b \u0437\u0430\u043a\u043e\u043d\u0441\u043f\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u044d\u0442\u043e\u0442 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/de\/blog\/news\/asinhronnoe-programmirovanie-v-javascript-callback-promise-rxjs\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.1.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"de_DE\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u0410\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0432 JavaScript. ( Callback, Promise, RxJs ) | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442. \u041d\u0430 \u0441\u0432\u044f\u0437\u0438 \u041e\u043c\u0435\u043b\u044c\u043d\u0438\u0446\u043a\u0438\u0439 \u0421\u0435\u0440\u0433\u0435\u0439. \u041d\u0435 \u0442\u0430\u043a \u0434\u0430\u0432\u043d\u043e \u044f \u0432\u0435\u043b \u0441\u0442\u0440\u0438\u043c \u043f\u043e \u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u043e\u043c\u0443 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044e, \u0433\u0434\u0435 \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u043b \u043f\u0440\u043e \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0441\u0442\u044c \u0432 JavaScript. \u0421\u0435\u0433\u043e\u0434\u043d\u044f \u044f \u0431\u044b \u0445\u043e\u0442\u0435\u043b \u0437\u0430\u043a\u043e\u043d\u0441\u043f\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u044d\u0442\u043e\u0442 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/de\/blog\/news\/asinhronnoe-programmirovanie-v-javascript-callback-promise-rxjs\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-10-31T19:13:44+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2019-10-31T19:13:44+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Asynchrones Programmieren in JavaScript. (Callback, Promise, RxJS) | ProHoster","description":"Hallo zusammen. Hier ist Sergey Omelnitsky. Vor kurzem habe ich einen Livestream zum reaktiven Programmieren gehalten, in dem ich \u00fcber Asynchronit\u00e4t in JavaScript gesprochen habe. Heute m\u00f6chte ich dieses Material zusammenfassen.","canonical_url":"https:\/\/prohoster.info\/de\/blog\/news\/asinhronnoe-programmirovanie-v-javascript-callback-promise-rxjs","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"de_DE","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u0410\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0432 JavaScript. ( Callback, Promise, RxJs ) | ProHoster","og:description":"\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442. \u041d\u0430 \u0441\u0432\u044f\u0437\u0438 \u041e\u043c\u0435\u043b\u044c\u043d\u0438\u0446\u043a\u0438\u0439 \u0421\u0435\u0440\u0433\u0435\u0439. \u041d\u0435 \u0442\u0430\u043a \u0434\u0430\u0432\u043d\u043e \u044f \u0432\u0435\u043b \u0441\u0442\u0440\u0438\u043c \u043f\u043e \u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u043e\u043c\u0443 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044e, \u0433\u0434\u0435 \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u043b \u043f\u0440\u043e \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0441\u0442\u044c \u0432 JavaScript. \u0421\u0435\u0433\u043e\u0434\u043d\u044f \u044f \u0431\u044b \u0445\u043e\u0442\u0435\u043b \u0437\u0430\u043a\u043e\u043d\u0441\u043f\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u044d\u0442\u043e\u0442 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b.","og:url":"https:\/\/prohoster.info\/de\/blog\/news\/asinhronnoe-programmirovanie-v-javascript-callback-promise-rxjs","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2019-10-31T19:13:44+00:00","article:modified_time":"2019-10-31T19:13:44+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"36774","title":null,"description":null,"keywords":null,"keyphrases":{"focus":[],"additional":[]},"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":"2026-01-22 04:48:19","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-03-01 01:39:22","updated":"2026-08-11 12:50:32","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/posts\/36774","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/comments?post=36774"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/posts\/36774\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/media\/27545"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/media?parent=36774"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/categories?post=36774"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/tags?post=36774"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}