{"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\/nl\/blog\/news\/asinhronnoe-programmirovanie-v-javascript-callback-promise-rxjs","title":{"rendered":"Asynchroon programmeren in JavaScript. (Callback, Promise, RxJs)","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Hallo iedereen. Sergei Omelnitsky hier. Onlangs heb ik een livestream gedaan over reactief programmeren, waarin ik sprak over asynchroniciteit in JavaScript. Vandaag wil ik dit materiaal samenvatten. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynchroon programmeren 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>Maar voordat we met het hoofdonderwerp beginnen, moeten we een inleiding maken. Laten we beginnen met definities: wat zijn een stapel en een wachtrij?<br \/>\n<strong>Stapel <\/strong>is een collectie waarvan de elementen volgens het principe 'laatst binnen, eerst eruit' LIFO worden verkregen.<br \/>\n<strong>Wachtrij <\/strong>is een collectie waarvan de elementen volgens het principe 'eerste in, eerste uit' FIFO worden verkregen.<\/p>\n<p><\/p>\n<p>Ok\u00e9, laten we verder gaan. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynchroon programmeren 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 is een single-threaded programmeertaal. Dit betekent dat er slechts \u00e9\u00e9n uitvoeringsdraad en \u00e9\u00e9n stapel is waarin functies in de wachtrij voor uitvoering worden geplaatst. Dus kan JavaScript op elk moment slechts \u00e9\u00e9n operatie uitvoeren; andere operaties moeten wachten in de stapel totdat ze worden opgeroepen. <\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<p><strong>De oproepstapel<\/strong> is een datastructuur die samengevat informatie opschrijft over waar we in het programma zijn. Wanneer we een functie ingaan, plaatsen we een record daarvan bovenaan de stapel. Wanneer we uit de functie terugkeren, halen we het bovenste element van de stapel en komen we daar waar we deze functie hebben opgeroepen. Dat is alles wat de stapel doet. En nu een zeer interessante vraag. Hoe werkt asynchroniciteit in JavaScript dan?<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynchroon programmeren 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>In feite is er naast de stapel in browsers een speciale wachtrij voor het werken met het zogenaamde WebAPI. Functies uit deze wachtrij worden alleen in volgorde uitgevoerd nadat de stapel volledig is geleegd. Pas daarna worden ze van de wachtrij naar de stapel verplaatst voor uitvoering. Als er momenteel minstens \u00e9\u00e9n element in de stapel zit, kunnen ze de stapel niet binnenkomen. Dit is precies de reden waarom aanroeptijden van functies met time-outs vaak onnauwkeurig zijn, omdat een functie de stapel niet binnen kan gaan zolang deze vol is. <\/p>\n<p><\/p>\n<p>Laten we het volgende voorbeeld bekijken en het stap voor stap 'uitvoeren'. Laten we ook zien wat er in het systeem gebeurt.<\/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=\"Asynchroon programmeren 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) Ondertussen gebeurt er niets. De browserconsole is leeg, de oproepstapel is leeg.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynchroon programmeren 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) Vervolgens wordt de opdracht console.log(&#8216;Hi&#8217;) aan de oproepstack toegevoegd.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynchroon programmeren 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) En het wordt uitgevoerd.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynchroon programmeren 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) Daarna wordt console.log(&#8216;Hi&#8217;) uit de oproepstack verwijderd.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynchroon programmeren 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) Laten we nu kijken naar het commando setTimeout(function cb1() {\u2026 }). Het wordt aan de call stack toegevoegd.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynchroon programmeren 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) Het commando setTimeout(function cb1() {\u2026 }) wordt uitgevoerd. De browser cre\u00ebert een timer die onderdeel is van de Web API. Deze zal de tijd aftellen.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynchroon programmeren 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) Het commando setTimeout(function cb1() {\u2026 }) is voltooid en wordt uit de call stack verwijderd.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynchroon programmeren 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) De opdracht console.log(&#8216;Bye&#8217;) wordt aan de oproepstack toegevoegd.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynchroon programmeren 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) De opdracht console.log(&#8216;Bye&#8217;) wordt uitgevoerd.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynchroon programmeren 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) De opdracht console.log(&#8216;Bye&#8217;) wordt uit de oproepstack verwijderd.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynchroon programmeren 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) Nadat er minstens 5000 ms zijn verstreken, voltooit de timer zijn werk en plaatst de callback cb1 in de callback queue.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynchroon programmeren 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) De event loop neemt de functie cb1 uit de callback queue en plaatst deze in de call stack.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynchroon programmeren 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) De functie cb1 wordt uitgevoerd en voegt console.log(&#8216;cb1&#8217;) toe aan de oproepstack.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynchroon programmeren 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) De opdracht console.log(&#8216;cb1&#8217;) wordt uitgevoerd.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynchroon programmeren 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) De opdracht console.log(&#8216;cb1&#8217;) wordt uit de oproepstack verwijderd.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynchroon programmeren 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) De functie cb1 wordt uit de call stack verwijderd.<\/p>\n<p><\/p>\n<p>Laten we eens kijken naar een voorbeeld in actie:<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynchroon programmeren 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>Dus we hebben besproken hoe asynchroniciteit in JavaScript wordt gerealiseerd. Laten we nu kort praten over de evolutie van asynchrone code.<\/p>\n<p><\/p>\n<h2 id=\"evolyuciya-asinhronnogo-koda\">De evolutie van asynchrone code.<\/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>Asynchroon programmeren, zoals we het in JavaScript kennen, kan enkel worden gerealiseerd met functies. Ze kunnen zoals elke andere variabele aan andere functies worden doorgegeven. Zo zijn callbacks ontstaan. En dat is leuk, grappig en spannend, totdat het verandert in verdriet, melancholie en verdriet. Waarom? Gewoon omdat:<\/p>\n<p><\/p>\n<ul>\n<li>Met de toenemende complexiteit van de code verandert het project al snel in moeilijk te begrijpen, meerdere geneste blokken \u2014 'callback hell'.<\/li>\n<li>Foutafhandeling kan gemakkelijk worden gemist.<\/li>\n<li>Je kunt geen waarden teruggeven met return.<\/li>\n<\/ul>\n<p><\/p>\n<p>Met de komst van Promise is de situatie iets beter geworden.<\/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>Er zijn ketens van beloftes ontstaan, wat de leesbaarheid van de code verbeterde.<\/li>\n<li>Er is een aparte methode voor foutafhandeling gekomen.<\/li>\n<li>Er is de mogelijkheid voor parallelle uitvoering met Promise.all gekomen.<\/li>\n<li>We kunnen geneste asynchroniteit oplossen met async\/await<\/li>\n<\/ul>\n<p><\/p>\n<p>Maar een belofte heeft zijn eigen beperkingen. Bijvoorbeeld, een belofte kan niet worden geannuleerd zonder ingewikkelde trucs, en het belangrijkste is dat het met \u00e9\u00e9n waarde werkt.<\/p>\n<p><\/p>\n<p>Hier zijn we dan bij reactief programmeren. Moe? Gelukkig kun je even een kopje thee zetten, erover nadenken en later verder lezen. Ik ga intussen door.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynchroon programmeren 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>Reactief programmeren<\/strong>\u200a\u2014\u200ais een programmeerparadigma dat zich richt op datastromen en het verspreiden van wijzigingen. Laten we eens dieper ingaan op wat een datastroom is.<\/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>Stel je voor dat we een invoerveld hebben. We cre\u00ebren een array, en bij elke keyup gebeurtenis van de input slaan we het evenement op in onze array. Daarbij willen we opmerken dat onze array op tijd is gesorteerd, dat wil zeggen: de index van latere gebeurtenissen is groter dan die van eerdere. Zo'n array stelt een vereenvoudigd model van een datastroom voor, maar dit is nog geen stroom. Om deze array met recht een stroom te noemen, moet hij op de een of andere manier kunnen communiceren met abonnees dat er nieuwe gegevens zijn binnengekomen. Zo zijn we tot de definitie van een datastroom gekomen.<\/p>\n<p><\/p>\n<h3 id=\"potok-dannyh\">Datastroom<\/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=\"Asynchroon programmeren 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>Stroom\u200a<\/strong>\u2014\u200ais een array van gegevens, gesorteerd op tijd, die kan aangeven dat de gegevens zijn gewijzigd. En stel je voor hoe handig het wordt om code te schrijven waarbij \u00e9\u00e9n actie meerdere gebeurtenissen in verschillende delen van de code vereist. We abonneren ons gewoon op de stroom en deze zal ons zelf informeren wanneer er wijzigingen plaatsvinden. Dit kan de RxJs bibliotheek.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynchroon programmeren 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 is een bibliotheek voor het werken met asynchrone en gebeurtenisgestuurde programma's met behulp van observeerbare reeksen. De bibliotheek biedt het belangrijkste type <em>Observable<\/em>, enkele hulpprogramma's (<em>Observer, Schedulers, Subjects<\/em>) en operators voor het werken met gebeurtenissen als collecties (<em>map, filter, reduce, every<\/em> en soortgelijke uit de JavaScript Array).<\/p>\n<p><\/p>\n<p>Laten we de belangrijkste concepten van deze bibliotheek eens bekijken.<\/p>\n<p><\/p>\n<h3 id=\"observable-observer-producer\">Observable, Observer, Producer<\/h3>\n<p><\/p>\n<p>Observable is het eerste basisgegevenstype dat we zullen bespreken. Deze klasse bevat het belangrijkste deel van de implementatie van RxJs. Het is verbonden met de observeerbare stroom waarop je je kunt abonneren met de subscribe-methode.<\/p>\n<p><\/p>\n<p>In Observable is an auxiliary mechanism implemented for creating updates, known as <em>Observer<\/em>. The source of values for an Observer is called <em>Producer<\/em>. This can be an array, an iterator, a web socket, some event, etc. So we can say that an observable is a conduit between Producer and Observer. <\/p>\n<p><\/p>\n<p>Observable processes three types of Observer events:<\/p>\n<p><\/p>\n<ul>\n<li>next \u2013 new data<\/li>\n<li>error \u2013 an error if the sequence is completed due to an exceptional situation. This event also implies the completion of the sequence.<\/li>\n<li>complete \u2013 a signal that the sequence is finished. This means that there will be no more new data<\/li>\n<\/ul>\n<p><\/p>\n<p>Let's look at a demo:<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynchroon programmeren 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>At first, we will process the values 1, 2, 3, and after 1 second, we will get 4 and complete our stream.<\/p>\n<p>\n<b class=\"spoiler_title\">Thinking out loud<\/b><\/p>\n<p>And then I realized that telling the story was more interesting than writing about it. \ud83d\ude00 <\/p>\n<p><\/p>\n<h3 id=\"subscription\">Subscription<\/h3>\n<p><\/p>\n<p>When we subscribe to a stream, we create a new class <strong>subscription<\/strong>, which allows us to cancel the subscription using the method <em>unsubscribe<\/em>. We can also group subscriptions using the method <em>add<\/em>. And logically, we can ungroup streams using <em>verwijder<\/em>. The add and remove methods accept another subscription as input. I would like to note that when we unsubscribe, we unsubscribe from all child subscriptions as if we called the unsubscribe method on them. Let's move on.<\/p>\n<p><\/p>\n<h3 id=\"vidy-potokov\">Types of 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 is created outside of observable<\/td>\n<td>Producer is created inside observable<\/td>\n<\/tr>\n<tr>\n<td>Data is transmitted at the moment of observable creation<\/td>\n<td>Data is communicated at the moment of subscription<\/td>\n<\/tr>\n<tr>\n<td>Additional logic is needed for unsubscription<\/td>\n<td>The stream ends by itself<\/td>\n<\/tr>\n<tr>\n<td>Uses a one-to-many relationship<\/td>\n<td>Uses a one-to-one relationship<\/td>\n<\/tr>\n<tr>\n<td>All subscriptions have a unified value<\/td>\n<td>Subscriptions are independent<\/td>\n<\/tr>\n<tr>\n<td>Data can be lost if there is no subscription<\/td>\n<td>Reissues all values of the stream for the new subscription<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><\/p>\n<p>If I were to draw an analogy, I would picture a hot stream as a movie in a cinema. At whatever moment you arrive, you start watching from that point. I would compare a cold stream to a call to tech support. Any caller listens to the auto-responder recording from start to finish, but you can hang up using unsubscribe.<\/p>\n<p><\/p>\n<p>Ik wil opmerken dat er ook zogenaamde warme stromen bestaan (dit begrip kwam ik uiterst zelden tegen en alleen in buitenlandse gemeenschappen) \u2014 dit is een stroom die transformeert van een koude stroom naar een hete. De vraag rijst \u2014 waar gebruik je dit voor)) Ik zal een voorbeeld uit de praktijk geven.<\/p>\n<p><\/p>\n<p>Ik werk met Angular. Het maakt actief gebruik van RxJS. Voor het ophalen van gegevens van de server verwacht ik een koude stroom en gebruik deze stroom in de sjabloon met behulp van AsyncPipe. Als ik deze pipe meerdere keren gebruik, dan zal, terugkerend naar de definitie van een koude stroom, elke pipe gegevens van de server opvragen, wat zacht gezegd vreemd is. Maar als ik de koude stroom omzet in een warme, zal de aanvraag slechts \u00e9\u00e9n keer plaatsvinden.<\/p>\n<p><\/p>\n<p>Eigenlijk is het begrip van de soorten stromen vrij complex voor beginners, maar het is belangrijk. <\/p>\n<p><\/p>\n<h3 id=\"operators\">Operators<\/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>De mogelijkheid om met stromen te werken wordt ons geboden door operators. Ze helpen evenementen te beheersen die plaatsvinden binnen de Observable. We zullen een paar van de meest populaire bekijken, en voor een gedetailleerde uitleg over operators kun je de links in de nuttige informatie raadplegen.<\/p>\n<p><\/p>\n<p><strong>Operators \u2014 of<\/strong><\/p>\n<p><\/p>\n<p>Laten we beginnen met de hulpopperator 'of'. Hij cre\u00ebert een Observable op basis van een eenvoudige waarde.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynchroon programmeren 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>Operators \u2014 filter<\/strong><\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynchroon programmeren 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>De filteroperator filter, zoals je uit de naam kunt afleiden, filtert het stroomsignaal. Als de operator waar teruggeeft, laat hij het verder doorgaan.<\/p>\n<p><\/p>\n<p><strong>Operators \u2014 take<\/strong><\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynchroon programmeren 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 Neemt het aantal emissies aan, waarna de stroom wordt be\u00ebindigd.<\/p>\n<p><\/p>\n<p><strong>Operators \u2014 debounceTime<\/strong><\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynchroon programmeren 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 Negeert de uitgespuwde waarden die binnen het opgegeven tijdsinterval tussen de output komen \u2014 na het verstrijken van het tijdsinterval geeft het de laatste waarde uit.<\/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  \/\/ Geeft waarde elke 1000ms uit\n  setInterval(() =&gt; {\n    observer.next(i++)\n  }, 1000);\n\n \/\/ Geeft waarde elke 1500ms uit\n  setInterval(() =&gt; {\n    observer.next(i++)\n  }, 1500);\n}).pipe(\n  debounceTime(700),  \/\/ Wacht 700ms op waarde voordat deze verwerkt wordt\n  take(3)\n);  <\/code><\/pre>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynchroon programmeren 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>Operators \u2014 takeWhile<\/strong><\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynchroon programmeren 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>Geeft waarden uit zolang takeWhile geen false retourneert, waarna het zich afmeldt van de stroom.<\/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  \/\/ Stoot een waarde uit om de 1000 ms\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=\"Asynchroon programmeren 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>Operators \u2014 combineLatest<\/strong><\/p>\n<p><\/p>\n<p>De gecombineerde operator combineLatest lijkt op promise.all. Het combineert meerdere streams tot \u00e9\u00e9n. Zodra elke stream ten minste \u00e9\u00e9n emit heeft gedaan, krijgen we de laatste waarden van elk in de vorm van een array. Vervolgens, na elke emissie van de gecombineerde streams, geeft het nieuwe waarden terug.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynchroon programmeren 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  \/\/ Stoot een waarde uit om de 1000 ms\n  setInterval(() =&gt; {\n    observer.next('a: ' + i++);\n  }, 1000);\n});\n\nconst observer_2 = Observable.create((observer) =&gt; {\n  let i = 1;\n  \/\/ Stoot een waarde uit om de 750 ms\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=\"Asynchroon programmeren 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>Operators \u2014 zip<\/strong><\/p>\n<p><\/p>\n<p>Zip wacht op een waarde uit elke stream en vormt een array op basis van deze waarden. Als er geen waarde uit een bepaalde stream komt, wordt de groep niet gevormd.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynchroon programmeren 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  \/\/ Stoot een waarde uit om de 1000 ms\n  setInterval(() =&gt; {\n    observer.next('a: ' + i++);\n  }, 1000);\n});\n\nconst observer_2 = Observable.create((observer) =&gt; {\n  let i = 1;\n  \/\/ Stoot een waarde uit om de 750 ms\n  setInterval(() =&gt; {\n    observer.next('b: ' + i++);\n  }, 750);\n});\n\nconst observer_3 = Observable.create((observer) =&gt; {\n  let i = 1;\n  \/\/ Stoot een waarde uit om de 500 ms\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=\"Asynchroon programmeren 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>Operators \u2014 forkJoin<\/strong><\/p>\n<p><\/p>\n<p>forkJoin combineert ook streams, maar het emit alleen een waarde wanneer alle streams zijn be\u00ebindigd (complete).<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynchroon programmeren 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  \/\/ Stoot een waarde uit om de 1000 ms\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  \/\/ Stoot een waarde uit om de 750\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  \/\/ Stoot een waarde uit om de 500\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=\"Asynchroon programmeren 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>Operators \u2014 map<\/strong><\/p>\n<p><\/p>\n<p>De transformaties operator map verandert de waarde van de emit in een nieuwe. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynchroon programmeren 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  \/\/ Stoot een waarde uit om de 1000 ms\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=\"Asynchroon programmeren 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>Operators \u2013 share, tap<\/strong><\/p>\n<p><\/p>\n<p>De tap-operator &#8212; stelt je in staat om side-effecten te cre\u00ebren, dat wil zeggen, acties die geen invloed hebben op de volgorde.<\/p>\n<p><\/p>\n<p>De utility-operator share kan een koude stroom omzetten in een warme. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynchroon programmeren 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>We hebben de operators afgerond. Laten we doorgaan naar Subject.<\/p>\n<p>\n<b class=\"spoiler_title\">Thinking out loud<\/b><\/p>\n<p>En toen ging ik thee drinken. Deze voorbeelden hebben me uitgeput \ud83d\ude00<\/p>\n<p><\/p>\n<h2 id=\"semeystvo-subject-ov\">Familie van subjects<\/h2>\n<p><\/p>\n<p>De familie van subjects is een mooi voorbeeld van warme stromen. Deze klassen zijn een soort hybride die tegelijkertijd als observable en observer optreden. Omdat het subject een warme stroom is, moet je je afmelden. Wat betreft de belangrijkste methoden zijn dat:<\/p>\n<p><\/p>\n<ul>\n<li>next \u2013 nieuwe data doorgeven naar de stroom<\/li>\n<li>error \u2013 fout en be\u00ebindiging van de stroom<\/li>\n<li>complete \u2013 be\u00ebindiging van de stroom<\/li>\n<li>subscribe \u2013 abonneren op de stroom<\/li>\n<li>unsubscribe \u2013 afmelden van de stroom<\/li>\n<li>asObservable \u2013 omzetten naar observer<\/li>\n<li>toPromise \u2013 omzetten naar promise<\/li>\n<\/ul>\n<p><\/p>\n<p>Er zijn 4 tot 5 typen subjects. <\/p>\n<p>\n<b class=\"spoiler_title\">Thinking out loud<\/b><\/p>\n<p>Ik zei 4 op de stream, maar blijkbaar hebben ze er nog een toegevoegd. Zoals het gezegde luidt: 'een leven lang leren'.<\/p>\n<p><\/p>\n<p>Eenvoudig Subject <code>new Subject()<\/code>\u2013 de eenvoudigste vorm van subjects. Wordt zonder parameters gemaakt. Geeft alleen waarden door die na de aanmelding zijn gekomen.<\/p>\n<p><\/p>\n<p>BehaviorSubject <code>new BehaviorSubject(defaultData)<\/code> \u2013 naar mijn mening de meest voorkomende vorm van subjects. Neemt een standaardwaarde als invoer. Bewaart altijd de gegevens van de laatste emissie, die het doorgeeft bij aanmelding. Deze klasse heeft ook een nuttige waarde methode die de huidige waarde van de stroom retourneert.<\/p>\n<p><\/p>\n<p>ReplaySubject <code>new ReplaySubject(bufferSize?: number, windowTime?: number)<\/code> \u2013 Kan optioneel een buffermaat voor de waarden aannemen die het zal opslaan als eerste argument, en als tweede argument de tijd waarin we wijzigingen nodig hebben.<\/p>\n<p><\/p>\n<p>AsyncSubject <code>new AsyncSubject()<\/code> \u2013 bij aanmelding gebeurt er niets, en de waarde wordt alleen geretourneerd bij complete. Er zal alleen de laatste waarde van de stroom worden geretourneerd.<\/p>\n<p><\/p>\n<p>WebSocketSubject <code>new WebSocketSubject(urlConfigOrSource: string | WebSocketSubjectConfig | Observable, destination?: Observer)<\/code> \u2013 De documentatie zegt er niets over en ik zie het voor het eerst. Wie weet wat het doet, laat het me weten, dan vullen we het aan.<\/p>\n<p><\/p>\n<p>Phew. Nou, dat was alles wat ik vandaag wilde bespreken. Ik hoop dat deze informatie nuttig was. Je kunt de literatuurlijst zelf bekijken in het tabblad nuttige informatie.<\/p>\n<p><\/p>\n<h2 id=\"poleznaya-informaciya\">Nuttige informatie<\/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 naar de 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 Hoe JS werkt: overzicht van de motor, uitvoeringsmechanismen, oproepstack<\/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 Hoe JS werkt: de event loop, asynchroniciteit en vijf manieren om code te verbeteren met 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 Hoe de Event Loop in JavaScript werkt<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/tproger.ru\/translations\/asynchronous-javascript\/\">https:\/\/tproger.ru\/translations\/asynchronous-javascript\/<\/a><\/noindex> \u2014 De evolutie van asynchroon 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 Wat is RxJS en waarom is het nuttig om erover te weten<\/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 toepassing van 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 Cre\u00ebren &amp; Abonneren op 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: Heet en Koud Observables<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/clck.ru\/FiPgB\">https:\/\/clck.ru\/FiPgB<\/a><\/noindex> \u2014 Klassen, functies voor het maken van Observable. Operators.<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/www.learnrxjs.io\/operators\/\">https:\/\/www.learnrxjs.io\/operators\/<\/a><\/noindex> \u2014 RxJS Operators aan de hand van voorbeelden<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/rxjs.dev\/api\">https:\/\/rxjs.dev\/api<\/a><\/noindex> \u2014 API Lijst<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/clck.ru\/FkS8Y\">https:\/\/clck.ru\/FkS8Y<\/a><\/noindex> \u2014 Typen Subject en Scheduling in RxJS<\/li>\n<\/ul>\n<p>Bron: <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.3 - 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\/nl\/blog\/news\/asinhronnoe-programmirovanie-v-javascript-callback-promise-rxjs\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.3\" \/>\n\t\t<meta property=\"og:locale\" content=\"nl_NL\" \/>\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\/nl\/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\udd47Asynchroon programmeren in JavaScript. ( Callback, Promise, RxJs ) | ProHoster","description":"Hallo iedereen. Sergei Omelnitsky hier. Onlangs heb ik een livestream gedaan over reactief programmeren, waarin ik sprak over asynchroniciteit in JavaScript. Vandaag wil ik dit materiaal samenvatten.","canonical_url":"https:\/\/prohoster.info\/nl\/blog\/news\/asinhronnoe-programmirovanie-v-javascript-callback-promise-rxjs","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"nl_NL","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\/nl\/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\/nl\/wp-json\/wp\/v2\/posts\/36774","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/comments?post=36774"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/posts\/36774\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/media\/27545"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/media?parent=36774"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/categories?post=36774"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/tags?post=36774"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}