{"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\/sv\/blog\/news\/asinhronnoe-programmirovanie-v-javascript-callback-promise-rxjs","title":{"rendered":"Asynkron programmering i JavaScript. (Callback, Promise, RxJs)","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Hej alla. Det \u00e4r Omlnytsky Sergey h\u00e4r. F\u00f6r inte s\u00e5 l\u00e4nge sedan h\u00f6ll jag en str\u00f6m om reaktiv programmering, d\u00e4r jag pratade om asynkronitet i JavaScript. Idag skulle jag vilja sammanfatta detta material. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynkron programmering i JavaScript. (Callback, Promise, RxJs)\" src=\"\/wp-content\/uploads\/2019\/08\/11acf6af8328d3deb6f0ce48e813efb7.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Men innan vi b\u00f6rjar med huvuddelen av materialet beh\u00f6ver vi g\u00f6ra en introduktion. S\u00e5, l\u00e5t oss b\u00f6rja med definitionerna: vad \u00e4r en stack och en k\u00f6?<br \/>\n<strong>Stack <\/strong>\u2014 \u00e4r en samling d\u00e4r elementen h\u00e4mtas enligt principen \"senast in, f\u00f6rst ut\" LIFO.<br \/>\n<strong>K\u00f6 <\/strong>\u2014 \u00e4r en samling d\u00e4r elementen h\u00e4mtas enligt principen \"f\u00f6rst in, f\u00f6rst ut\" FIFO.<\/p>\n<p><\/p>\n<p>Okej, vi forts\u00e4tter. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynkron programmering i 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 \u00e4r ett enskilt tr\u00e5dat programmeringsspr\u00e5k. Det betyder att det bara finns en k\u00f6rtr\u00e5d och en stack d\u00e4r funktionerna placeras i k\u00f6 f\u00f6r utf\u00f6rande. F\u00f6ljaktligen kan JavaScript vid ett givet \u00f6gonblick bara utf\u00f6ra en operation, medan andra operationer v\u00e4ntar p\u00e5 sin tur i stacken tills de kallas. <\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<p><strong>Anropsstack<\/strong> \u2014 \u00e4r en databasstruktur som, f\u00f6renklat sagt, registrerar information om var vi befinner oss i programmet. N\u00e4r vi g\u00e5r in i en funktion, placerar vi en post om den h\u00f6gst upp i stacken. N\u00e4r vi \u00e5terv\u00e4nder fr\u00e5n funktionen tar vi bort det \u00f6versta elementet fr\u00e5n stacken och hamnar d\u00e4r vi kallade funktionen. Det \u00e4r allt som stacken kan g\u00f6ra. Men nu uppst\u00e5r den ytterst intressanta fr\u00e5gan. Hur fungerar d\u00e5 asynkroniteten i JavaScript?<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynkron programmering i JavaScript. (Callback, Promise, RxJs)\" src=\"\/wp-content\/uploads\/2019\/08\/a29fd1dd3de06fb203c7dd14bda30548.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>I sj\u00e4lva verket finns det, f\u00f6rutom stacken, en speciell k\u00f6 i webbl\u00e4sarna f\u00f6r arbete med s\u00e5 kallat WebAPI. Funktioner fr\u00e5n denna k\u00f6 kommer att utf\u00f6ras i ordning f\u00f6rst efter att stacken \u00e4r helt rensad. Endast efter detta placeras de fr\u00e5n k\u00f6n i stacken f\u00f6r utf\u00f6rande. Om det f\u00f6r n\u00e4rvarande finns minst ett element i stacken, kan de inte komma in i stacken. Just av den anledningen \u00e4r anrop av funktioner via timeout ofta tidsm\u00e4ssigt oexakta, eftersom funktionen inte kan komma fr\u00e5n k\u00f6n till stacken s\u00e5 l\u00e4nge den \u00e4r fylld. <\/p>\n<p><\/p>\n<p>L\u00e5t oss titta p\u00e5 f\u00f6ljande exempel och g\u00e5 igenom dess \"utf\u00f6rande\" steg f\u00f6r steg. L\u00e5t oss ocks\u00e5 titta p\u00e5 vad som h\u00e4nder i systemet.<\/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=\"Asynkron programmering i 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) Inga h\u00e4ndelser f\u00f6r tillf\u00e4llet. Webbl\u00e4sarens konsol \u00e4r tom, anropsstacken \u00e4r tom.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynkron programmering i 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) Sedan l\u00e4ggs kommandot console.log('Hi') till i anropstacken.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynkron programmering i 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) Och den utf\u00f6rs<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynkron programmering i 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) D\u00e4refter tas console.log('Hi') bort fr\u00e5n anropstacken.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynkron programmering i 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) Nu g\u00e5r vi vidare till kommandot setTimeout(function cb1() {\u2026 }). Det l\u00e4ggs till i anropsstacken.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynkron programmering i 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) Kommandot setTimeout(function cb1() {\u2026 }) utf\u00f6rs. Webbl\u00e4saren skapar en timer, som \u00e4r en del av Web API. Den kommer att r\u00e4kna ner tiden.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynkron programmering i 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) Kommandot setTimeout(function cb1() {\u2026 }) har slutf\u00f6rt sin uppgift och tas bort fr\u00e5n anropsstacken.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynkron programmering i 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) Kommandot console.log('Bye') l\u00e4ggs till i anropstacken.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynkron programmering i 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) Kommandot console.log('Bye') utf\u00f6rs.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynkron programmering i 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) Kommandot console.log('Bye') tas bort fr\u00e5n anropstacken.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynkron programmering i 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) N\u00e4r minst 5000 ms har g\u00e5tt, avslutar timern sin uppgift och placerar callback cb1 i callback-k\u00f6n.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynkron programmering i 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) Event loop tar funktionen cb1 fr\u00e5n callback-k\u00f6n och l\u00e4gger den i anropsstacken.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynkron programmering i 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) Funktionen cb1 utf\u00f6rs och l\u00e4gger till console.log('cb1') i anropstacken.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynkron programmering i 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) Kommandot console.log('cb1') utf\u00f6rs.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynkron programmering i 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) Kommandot console.log('cb1') tas bort fr\u00e5n anropstacken.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynkron programmering i 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) Funktionen cb1 tas bort fr\u00e5n anropsstacken.<\/p>\n<p><\/p>\n<p>L\u00e5t oss titta p\u00e5 exemplet i dynamik:<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynkron programmering i JavaScript. (Callback, Promise, RxJs)\" src=\"\/wp-content\/uploads\/2019\/08\/3836d9df513afee374f498720990e39f.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Nu har vi g\u00e5tt igenom hur asynkronitet \u00e4r implementerat i JavaScript. L\u00e5t oss kort diskutera evolutionen av asynkron kod.<\/p>\n<p><\/p>\n<h2 id=\"evolyuciya-asinhronnogo-koda\">Evolutionen av asynkron kod.<\/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>Asynkront programmering, som vi k\u00e4nner det i JavaScript, kan endast genomf\u00f6ras av funktioner. De kan \u00f6verf\u00f6ras som vilken annan variabel som helst till andra funktioner. S\u00e5 f\u00f6ddes callbacks. Och det \u00e4r roligt och underh\u00e5llande, tills det f\u00f6rvandlas till sorg och el\u00e4nde. Varf\u00f6r? Jo, helt enkelt:<\/p>\n<p><\/p>\n<ul>\n<li>Med den \u00f6kande komplexiteten av koden, f\u00f6rvandlas projektet snabbt till sv\u00e5rbegripliga djupt inb\u00e4ddade block \u2014 \"callback hell\".<\/li>\n<li>Felhantering kan l\u00e4tt f\u00f6rbises.<\/li>\n<li>Det g\u00e5r inte att returnera uttryck med return.<\/li>\n<\/ul>\n<p><\/p>\n<p>Med inf\u00f6randet av Promise blev l\u00e4get n\u00e5got b\u00e4ttre.<\/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>Det kom kedjor av promisser, vilket f\u00f6rb\u00e4ttrade kodens l\u00e4sbarhet.<\/li>\n<li>Det kom en separat metod f\u00f6r att f\u00e5nga fel.<\/li>\n<li>M\u00f6jligheten till parallell exekvering har dykt upp med hj\u00e4lp av Promise.all<\/li>\n<li>Vi kan l\u00f6sa inb\u00e4ddad asynkronitet med hj\u00e4lp av async\/await<\/li>\n<\/ul>\n<p><\/p>\n<p>Men ett l\u00f6fte har sina begr\u00e4nsningar. Till exempel kan ett l\u00f6fte, utan extra kr\u00e5ngel, inte avbrytas, och det viktigaste \u00e4r - det fungerar med ett enda v\u00e4rde.<\/p>\n<p><\/p>\n<p>Nu har vi smidigt kommit till reaktiv programmering. Tr\u00f6tt? Tja, du kan brygga en kopp te, fundera lite och \u00e5terv\u00e4nda f\u00f6r att l\u00e4sa vidare. Jag forts\u00e4tter.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynkron programmering i 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>Reaktiv programmering<\/strong>\u00e4r en programmeringsparadigm inriktad p\u00e5 datastreamar och spridning av f\u00f6r\u00e4ndringar. L\u00e5t oss granska vad en datastream verkligen \u00e4r.<\/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>T\u00e4nk p\u00e5 att vi har ett inmatningsf\u00e4lt. Vi skapar en array, och p\u00e5 varje keyup-h\u00e4ndelse fr\u00e5n input kommer vi att lagra h\u00e4ndelsen i v\u00e5r array. Jag vill p\u00e5peka att v\u00e5r array \u00e4r sorterad efter tid - det vill s\u00e4ga, indexet f\u00f6r senare h\u00e4ndelser \u00e4r st\u00f6rre \u00e4n indexet f\u00f6r tidigare. En s\u00e5dan array representerar en f\u00f6renklad modell av en datastream, men det \u00e4r fortfarande inte en datastream. F\u00f6r att denna array ska kunna kallas en datastream m\u00e5ste den kunna meddela prenumeranterna om att nya data har kommit in. P\u00e5 s\u00e5 s\u00e4tt har vi kommit fram till definitionen av en datastream.<\/p>\n<p><\/p>\n<h3 id=\"potok-dannyh\">Datastream<\/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=\"Asynkron programmering i 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>Datastream<\/strong>\u00e4r en array av data sorterade efter tid som kan meddela n\u00e4r data har \u00e4ndrats. T\u00e4nk nu p\u00e5 hur bekv\u00e4mt det blir att skriva kod d\u00e4r en enda \u00e5tg\u00e4rd kr\u00e4ver att flera h\u00e4ndelser anropas p\u00e5 olika st\u00e4llen i koden. Vi g\u00f6r helt enkelt en prenumeration p\u00e5 datastreamen och den meddelar oss sj\u00e4lv n\u00e4r f\u00f6r\u00e4ndringar intr\u00e4ffar. Detta kan biblioteket RxJs g\u00f6ra.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynkron programmering i 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> \u00e4r ett bibliotek f\u00f6r att arbeta med asynkrona och h\u00e4ndelsebaserade program med hj\u00e4lp av observerbara sekvenser. Biblioteket tillhandah\u00e5ller den grundl\u00e4ggande typen <em>Observable<\/em>, n\u00e5gra hj\u00e4lptyper (<em>Observer, Schedulers, Subjects<\/em>) och operat\u00f6rer f\u00f6r att hantera h\u00e4ndelser som samlingar (<em>map, filter, reduce, every<\/em> och liknande fr\u00e5n JavaScript Array).<\/p>\n<p><\/p>\n<p>L\u00e5t oss g\u00e5 igenom de grundl\u00e4ggande begreppen i detta bibliotek.<\/p>\n<p><\/p>\n<h3 id=\"observable-observer-producer\">Observable, Observer, Producer<\/h3>\n<p><\/p>\n<p>Observable \u2014 den f\u00f6rsta grundl\u00e4ggande typen som vi kommer att titta p\u00e5. Denna klass inneh\u00e5ller huvuddelen av implementationen av RxJs. Den \u00e4r kopplad till det observerade fl\u00f6det som man kan prenumerera p\u00e5 med metoden subscribe.<\/p>\n<p><\/p>\n<p>I Observable implementeras en hj\u00e4lpfunktion f\u00f6r att skapa uppdateringar, s\u00e5 kallad <em>Observer<\/em>. K\u00e4llan till v\u00e4rden f\u00f6r Observer kallas <em>Producer<\/em>. Det kan vara en array, en iterator, web socket, n\u00e5got evenemang osv. S\u00e5 man kan s\u00e4ga att observable \u00e4r en f\u00f6rmedlare mellan Producer och Observer. <\/p>\n<p><\/p>\n<p>Observable hanterar tre typer av h\u00e4ndelser f\u00f6r Observer:<\/p>\n<p><\/p>\n<ul>\n<li>next \u2013 ny data<\/li>\n<li>error \u2013 ett fel om sekvensen avslutades p\u00e5 grund av ett undantag. Denna h\u00e4ndelse inneb\u00e4r ocks\u00e5 att sekvensen avslutas.<\/li>\n<li>complete \u2014 en signal om att sekvensen \u00e4r avslutad. Det betyder att det inte kommer att finnas fler data.<\/li>\n<\/ul>\n<p><\/p>\n<p>L\u00e5t oss se en demo:<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynkron programmering i JavaScript. (Callback, Promise, RxJs)\" src=\"\/wp-content\/uploads\/2019\/08\/c5bcd2af0f18b6de3ab0dbc20db595d1.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>I b\u00f6rjan kommer vi att bearbeta v\u00e4rdena 1, 2, 3, och efter 1 sekund kommer vi att f\u00e5 4 och avsluta v\u00e5rt fl\u00f6de.<\/p>\n<p>\n<b class=\"spoiler_title\">Tankar h\u00f6gt<\/b><\/p>\n<p>Och h\u00e4r ins\u00e5g jag att det var mer intressant att ber\u00e4tta \u00e4n att skriva om det. \ud83d\ude00 <\/p>\n<p><\/p>\n<h3 id=\"subscription\">Subscription<\/h3>\n<p><\/p>\n<p>N\u00e4r vi prenumererar p\u00e5 fl\u00f6det skapar vi en ny klass <strong>subscription<\/strong>, som ger oss m\u00f6jlighet att avbryta prenumerationen med metoden <em>unsubscribe<\/em>. Vi kan ocks\u00e5 gruppera prenumerationer med metoden <em>add<\/em>. Och det \u00e4r logiskt att vi kan avgruppera fl\u00f6den med hj\u00e4lp av <em>ta bort<\/em>. Metoderna add och remove tar en annan prenumeration som inparameter. Jag vill p\u00e5peka att n\u00e4r vi avbryter en prenumeration s\u00e5 avbryter vi ocks\u00e5 alla underordnade prenumerationer som om vi hade anropat metoden unsubscribe p\u00e5 dem. L\u00e5t oss g\u00e5 vidare.<\/p>\n<p><\/p>\n<h3 id=\"vidy-potokov\">Typer av fl\u00f6den<\/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 skapas utanf\u00f6r observable<\/td>\n<td>Producer skapas inuti observable<\/td>\n<\/tr>\n<tr>\n<td>Data skickas vid skapandet av observable<\/td>\n<td>Data rapporteras vid prenumerationen<\/td>\n<\/tr>\n<tr>\n<td>Ytterligare logik kr\u00e4vs f\u00f6r avprenumeration<\/td>\n<td>Fl\u00f6det avslutas automatiskt<\/td>\n<\/tr>\n<tr>\n<td>Anv\u00e4nder en ett-till-m\u00e5nga relation<\/td>\n<td>Anv\u00e4nder en ett-till-ett relation<\/td>\n<\/tr>\n<tr>\n<td>Alla prenumerationer har ett gemensamt v\u00e4rde<\/td>\n<td>Prenumerationerna \u00e4r oberoende<\/td>\n<\/tr>\n<tr>\n<td>Data kan g\u00e5 f\u00f6rlorad om det inte finns en prenumeration<\/td>\n<td>\u00c5terutger alla v\u00e4rden i fl\u00f6det f\u00f6r en ny prenumeration<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><\/p>\n<p>Om jag skulle f\u00f6ra en liknelse, skulle jag j\u00e4mf\u00f6ra en varm str\u00f6m med en film p\u00e5 bio. Fr\u00e5n det \u00f6gonblick du anl\u00e4nde, b\u00f6rjade du titta. Den kalla str\u00f6mmen skulle jag likna vid ett samtal till kundsupport. Den som ringer lyssnar p\u00e5 telefonsvararens meddelande fr\u00e5n b\u00f6rjan till slut, men du kan l\u00e4gga p\u00e5 luren genom att avprenumerera.<\/p>\n<p><\/p>\n<p>Jag vill p\u00e5peka att det ocks\u00e5 finns s\u00e5 kallade varma str\u00f6mmar (detta begrepp har jag sett extremt s\u00e4llan, och d\u00e5 endast p\u00e5 utl\u00e4ndska forum) - det \u00e4r en str\u00f6m som transformeras fr\u00e5n kall till varm. Fr\u00e5gan uppst\u00e5r - var ska man anv\u00e4nda det? Jag kommer att ge ett exempel fr\u00e5n praktiken.<\/p>\n<p><\/p>\n<p>Jag arbetar med Angular. Det anv\u00e4nder aktivt rxjs. F\u00f6r att h\u00e4mta data fr\u00e5n servern f\u00f6rv\u00e4ntar jag mig en kall str\u00f6m och anv\u00e4nder denna str\u00f6m i mallen med hj\u00e4lp av asyncPipe. Om jag anv\u00e4nder denna pipe flera g\u00e5nger, och \u00e5terg\u00e5r till definitionen av kall str\u00f6m, kommer varje pipe att beg\u00e4ra data fr\u00e5n servern, vilket med andra ord \u00e4r m\u00e4rkligt. Men om jag omvandlar den kalla str\u00f6mmen till en varm, s\u00e5 kommer beg\u00e4ran att ske en g\u00e5ng.<\/p>\n<p><\/p>\n<p>Att f\u00f6rst\u00e5 typer av str\u00f6mmar \u00e4r generellt ganska sv\u00e5rt f\u00f6r nyb\u00f6rjare, men det \u00e4r viktigt. <\/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>M\u00f6jligheterna att arbeta med str\u00f6mmar utvidgas av operat\u00f6rer. De hj\u00e4lper till att hantera h\u00e4ndelser som passerar genom Observable. Vi kommer att titta p\u00e5 n\u00e5gra av de mest popul\u00e4ra, och mer detaljerad information om operat\u00f6rer kan hittas via l\u00e4nkarna i den anv\u00e4ndbara informationen.<\/p>\n<p><\/p>\n<p><strong>Operators \u2014 of<\/strong><\/p>\n<p><\/p>\n<p>Vi b\u00f6rjar med hj\u00e4lpoperat\u00f6ren of. Den skapar en Observable baserat p\u00e5 ett enkelt v\u00e4rde.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynkron programmering i 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=\"Asynkron programmering i JavaScript. (Callback, Promise, RxJs)\" src=\"\/wp-content\/uploads\/2019\/08\/24ac65fdb5ccc7f6301b3dfe49f1e804.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Filteroperat\u00f6ren filter, som namnet antyder, filtrerar signalen i str\u00f6mmen. Om operat\u00f6ren returnerar sant, sl\u00e4pps den igenom.<\/p>\n<p><\/p>\n<p><strong>Operators \u2014 take<\/strong><\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynkron programmering i 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 - tar antalet emiterade v\u00e4rden som f\u00f6ljande str\u00f6m kommer att avsluta efter.<\/p>\n<p><\/p>\n<p><strong>Operators \u2014 debounceTime<\/strong><\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynkron programmering i 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 - kastar bort de emitterade v\u00e4rdena som faller inom det angivna tidsintervallet mellan utsignalerna - efter det tidsintervall, emitteras det sista v\u00e4rdet.<\/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  \/\/ Skickar v\u00e4rdet var 1000 ms\n  setInterval(() =&gt; {\n    observer.next(i++)\n  }, 1000);\n\n  \/\/ Skickar v\u00e4rdet var 1500 ms\n  setInterval(() =&gt; {\n    observer.next(i++)\n  }, 1500);\n}).pipe(\n  debounceTime(700),  \/\/ V\u00e4ntar 700 ms med v\u00e4rden innan de bearbetas\n  take(3)\n);  <\/code><\/pre>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynkron programmering i 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>Operat\u00f6rer \u2014 takeWhile<\/strong><\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynkron programmering i JavaScript. (Callback, Promise, RxJs)\" src=\"\/wp-content\/uploads\/2019\/08\/120d9fe6ddf5a60ddffc8742989b27ff.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Avger v\u00e4rden s\u00e5 l\u00e4nge takeWhile inte returnerar false, efter det avregistreras fr\u00e5n str\u00f6mmen.<\/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  \/\/ Skickar v\u00e4rdet var 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=\"Asynkron programmering i 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>Operat\u00f6rer \u2014 combineLatest<\/strong><\/p>\n<p><\/p>\n<p>CombineLatest-operat\u00f6ren liknar promise.all. Den sl\u00e5r samman flera str\u00f6mmar till en. N\u00e4r varje str\u00f6m har gjort minst en avvikelse f\u00e5r vi de senaste v\u00e4rdena fr\u00e5n varje som en array. Efter vilket som helst avvikelse fr\u00e5n de sammanfogade str\u00f6mmarna kommer den att ge nya v\u00e4rden.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynkron programmering i 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  \/\/ Skickar v\u00e4rdet var 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  \/\/ Skickar v\u00e4rdet var 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=\"Asynkron programmering i 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>Operat\u00f6rer \u2014 zip<\/strong><\/p>\n<p><\/p>\n<p>Zip \u2014 v\u00e4ntar p\u00e5 v\u00e4rde fr\u00e5n varje str\u00f6m och formar en array baserat p\u00e5 dessa v\u00e4rden. Om inget v\u00e4rde kommer fr\u00e5n n\u00e5gon str\u00f6m kommer gruppen inte att bildas.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynkron programmering i 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  \/\/ Skickar v\u00e4rdet var 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  \/\/ Skickar v\u00e4rdet var 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  \/\/ Skickar v\u00e4rdet var 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=\"Asynkron programmering i 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>Operat\u00f6rer \u2014 forkJoin<\/strong><\/p>\n<p><\/p>\n<p>forkJoin sl\u00e5r ocks\u00e5 samman str\u00f6mmarna, men den avger v\u00e4rden endast n\u00e4r alla str\u00f6mmar har avslutats (komplett).<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynkron programmering i 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  \/\/ S\u00e4nder v\u00e4rdet var 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  \/\/ S\u00e4nder v\u00e4rdet var 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  \/\/ S\u00e4nder v\u00e4rdet var 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=\"Asynkron programmering i 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>Operatorer \u2014 map<\/strong><\/p>\n<p><\/p>\n<p>Transformationsoperatorn map omvandlar v\u00e4rdet som emitteras till ett nytt. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynkron programmering i 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  \/\/ S\u00e4nder v\u00e4rdet var 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=\"Asynkron programmering i 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>Operatorer \u2013 share, tap<\/strong><\/p>\n<p><\/p>\n<p>Operatorn tap \u2014 till\u00e5ter att g\u00f6ra sid-effekter, det vill s\u00e4ga n\u00e5gon \u00e5tg\u00e4rd som inte p\u00e5verkar sekvensen.<\/p>\n<p><\/p>\n<p>Hj\u00e4lpoperatorn share kan g\u00f6ra en kallstr\u00f6m till en varmstr\u00f6m. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Asynkron programmering i JavaScript. (Callback, Promise, RxJs)\" src=\"\/wp-content\/uploads\/2019\/08\/c46e96420ed78d197ceef829ff74c82d.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Vi \u00e4r klara med operatorerna. L\u00e5t oss g\u00e5 vidare till Subject.<\/p>\n<p>\n<b class=\"spoiler_title\">Tankar h\u00f6gt<\/b><\/p>\n<p>Och h\u00e4r gick jag f\u00f6r att dricka te. Dessa exempel tr\u00f6ttade ut mig \ud83d\ude00<\/p>\n<p><\/p>\n<h2 id=\"semeystvo-subject-ov\">Familjen subject-er<\/h2>\n<p><\/p>\n<p>Familjen subject-er \u00e4r ett tydligt exempel p\u00e5 varma str\u00f6mmar. Dessa klasser \u00e4r en slags hybrid som fungerar b\u00e5de som observable och observer. Eftersom subject \u00e4r en varmstr\u00f6m, m\u00e5ste man avregistrera sig fr\u00e5n den. De huvudsakliga metoderna \u00e4r:<\/p>\n<p><\/p>\n<ul>\n<li>next \u2013 skicka nya data till str\u00f6mmen<\/li>\n<li>error \u2013 fel och avslutning av str\u00f6mmen<\/li>\n<li>complete \u2013 avslutning av str\u00f6mmen<\/li>\n<li>subscribe \u2013 prenumerera p\u00e5 str\u00f6mmen<\/li>\n<li>unsubscribe \u2013 avregistrera sig fr\u00e5n str\u00f6mmen<\/li>\n<li>asObservable \u2013 transformera till en observer<\/li>\n<li>toPromise \u2013 omvandlar till ett l\u00f6fte<\/li>\n<\/ul>\n<p><\/p>\n<p>Det finns 4\u20135 typer av subject-er. <\/p>\n<p>\n<b class=\"spoiler_title\">Tankar h\u00f6gt<\/b><\/p>\n<p>P\u00e5 streamen pratade jag om 4, men sedan visade det sig att de hade lagt till en till. Som man s\u00e4ger, l\u00e4r sig n\u00e5got nytt varje dag.<\/p>\n<p><\/p>\n<p>Enkel Subject <code>new Subject()<\/code>\u2013 den mest grundl\u00e4ggande typen av subject-er. Skapas utan parametrar. Skickar v\u00e4rden som kommer efter registrering.<\/p>\n<p><\/p>\n<p>BehaviorSubject <code>new BehaviorSubject(defaultData)<\/code> \u2013 enligt mig den mest spridda typen av subject-er. Tar ett standardv\u00e4rde som argument. Sparar alltid det senaste emiterade v\u00e4rdet som den skickar vid registrering. Denna klass har ocks\u00e5 en anv\u00e4ndbar metod, value, som returnerar det aktuella v\u00e4rdet i str\u00f6mmen.<\/p>\n<p><\/p>\n<p>ReplaySubject <code>new ReplaySubject(bufferSize?: number, windowTime?: number)<\/code> \u2013 kan som f\u00f6rsta argument valfritt ta storleken p\u00e5 buffern av v\u00e4rden som den kommer att lagra och som andra argument tiden under vilken vi beh\u00f6ver \u00e4ndringar.<\/p>\n<p><\/p>\n<p>AsyncSubject <code>ny AsyncSubject()<\/code> \u2014 vid prenumeration h\u00e4nder ingenting, och v\u00e4rdet kommer att returneras endast vid complete. Endast det senaste v\u00e4rdet fr\u00e5n str\u00f6mmen kommer att returneras.<\/p>\n<p><\/p>\n<p>WebSocketSubject <code>ny WebSocketSubject(urlConfigOrSource: string | WebSocketSubjectConfig&lt;T&gt; | Observable&lt;T&gt;, destination?: Observer&lt;T&gt;)<\/code> \u2014 Dokumentationen n\u00e4mner inte detta och jag ser det f\u00f6r f\u00f6rsta g\u00e5ngen sj\u00e4lv. Den som vet vad det g\u00f6r, skriv g\u00e4rna s\u00e5 vi kan komplettera.<\/p>\n<p><\/p>\n<p>Puh. N\u00e5v\u00e4l, vi har nu g\u00e5tt igenom allt jag ville ber\u00e4tta idag. Jag hoppas att denna information har varit nyttig. Du kan sj\u00e4lv bekanta dig med litteraturlistan under fliken nyttig information.<\/p>\n<p><\/p>\n<h2 id=\"poleznaya-informaciya\">Nyttig information<\/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> \u2014 l\u00e4nk till streamen<\/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> \u2014 Hur JS fungerar: \u00f6versikt av motorn, k\u00f6rrutiner, samt anropsstackar<\/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 Hur JS fungerar: evenemangslopp, asynkronitet och fem s\u00e4tt att f\u00f6rb\u00e4ttra koden med hj\u00e4lp av 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 Hur Event Loop fungerar i JavaScript<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/tproger.ru\/translations\/asynchronous-javascript\/\">https:\/\/tproger.ru\/translations\/asynchronous-javascript\/<\/a><\/noindex> \u2014 Utvecklingen av asynkront 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 Vad \u00e4r RxJS och varf\u00f6r \u00e4r det bra att k\u00e4nna till det<\/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 Praktisk till\u00e4mpning av 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 Skapa &amp; Prenumerera p\u00e5 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: Varma och kalla Observables<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/clck.ru\/FiPgB\">https:\/\/clck.ru\/FiPgB<\/a><\/noindex> \u2014 Klasser, funktioner f\u00f6r att skapa Observable. Operat\u00f6rer.<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/www.learnrxjs.io\/operators\/\">https:\/\/www.learnrxjs.io\/operators\/<\/a><\/noindex> \u2014 RxJS-operat\u00f6rer med exempel<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/rxjs.dev\/api\">https:\/\/rxjs.dev\/api<\/a><\/noindex> \u2014 API-lista<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/clck.ru\/FkS8Y\">https:\/\/clck.ru\/FkS8Y<\/a><\/noindex> \u2014 Olika slags Subject och Scheman i RxJS<\/li>\n<\/ul>\n<p>K\u00e4lla: <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.4 - 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\/sv\/blog\/news\/asinhronnoe-programmirovanie-v-javascript-callback-promise-rxjs\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.4\" \/>\n\t\t<meta property=\"og:locale\" content=\"sv_SE\" \/>\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\/sv\/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\udd47Asynkront programmerande i JavaScript. ( Callback, Promise, RxJs ) | ProHoster","description":"Hej alla. Det \u00e4r Omlnytsky Sergey h\u00e4r. F\u00f6r inte s\u00e5 l\u00e4nge sedan h\u00f6ll jag en str\u00f6m om reaktiv programmering, d\u00e4r jag pratade om asynkronitet i JavaScript. Idag skulle jag vilja sammanfatta detta material.","canonical_url":"https:\/\/prohoster.info\/sv\/blog\/news\/asinhronnoe-programmirovanie-v-javascript-callback-promise-rxjs","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"sv_SE","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\/sv\/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\/sv\/wp-json\/wp\/v2\/posts\/36774","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/comments?post=36774"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/posts\/36774\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/media\/27545"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/media?parent=36774"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/categories?post=36774"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/tags?post=36774"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}