{"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\/et\/blog\/novosti-interneta\/asinhronnoe-programmirovanie-v-javascript-callback-promise-rxjs","title":{"rendered":"As\u00fcnkroonne programmeerimine JavaScriptis. (Callback, Promise, RxJs)","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Tere k\u00f5igile. Siin on Omelnicki Sergei. Hiljuti viis ma l\u00e4bi voogesituse reaktiivse programmeerimise teemal, kus r\u00e4\u00e4kisin as\u00fcnkroonsusest JavaScriptis. T\u00e4na sooviksin selle materjali kokku v\u00f5tta. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"As\u00fcnkroonne programmeerimine JavaScriptis. (Callback, Promise, RxJs)\" src=\"\/wp-content\/uploads\/2019\/08\/11acf6af8328d3deb6f0ce48e813efb7.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Aga enne, kui alustame p\u00f5hiteemat, peame tegema sissejuhatuse. Niisiis, alustame definitsioonidest: mis on virn ja j\u00e4rjekord?<br \/>\n<strong>Virn <\/strong>\u2014 see on kollektsioon, mille elemendid saadakse \"viimane sisse, esimene v\u00e4lja\" LIFO p\u00f5him\u00f5ttel.<br \/>\n<strong>J\u00e4rjekord <\/strong>\u2014 see on kollektsioon, mille elemendid saadakse \"esimene sisse, esimene v\u00e4lja\" FIFO p\u00f5him\u00f5ttel.<\/p>\n<p><\/p>\n<p>Okei, j\u00e4tkame. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"As\u00fcnkroonne programmeerimine JavaScriptis. (Callback, Promise, RxJs)\" src=\"\/wp-content\/uploads\/2019\/08\/a7d64d1c74f37b463869dd57b96c9d0e.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>JavaScript on \u00fchesuunaline programmeerimiskeel. See t\u00e4hendab, et sellel on ainult \u00fcks t\u00e4itmisprotsess ja \u00fcks virn, kuhu funktsioonid j\u00e4etakse t\u00e4itmiseks ootele. Seega v\u00f5ib JavaScript korraga sooritada ainult \u00fche operatsiooni, teised operatsioonid ootavad oma j\u00e4rjekorda virnas, kuni neid kutsutakse. <\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<p><strong>Kutsumisvirn<\/strong> \u2014 see on andme struktuur, mis lihtsustatult \u00f6eldes salvestab teavet programmikohtade kohta, kus me asume. Kui me l\u00e4heme funktsiooni, paneme selle kohta kirje virna tippu. Kui me funktsioonist tagasi tuleme, t\u00f5mbame virnast v\u00e4lja k\u00f5ige \u00fclemise elemendi ja leiame end sealt, kust seda funktsiooni kutsuti. See on k\u00f5ik, mida virn oskab. Ja n\u00fc\u00fcd on v\u00e4ga huvitav k\u00fcsimus. Kuidas siis toimib as\u00fcnkroonsus JavaScriptis?<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"As\u00fcnkroonne programmeerimine JavaScriptis. (Callback, Promise, RxJs)\" src=\"\/wp-content\/uploads\/2019\/08\/a29fd1dd3de06fb203c7dd14bda30548.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Tegelikult on lisaks virnale brauserites eriline j\u00e4rjekord, mis tegeleb nii nimetatud WebAPI-ga. Selle j\u00e4rjekorra funktsioonid t\u00e4idetakse j\u00e4rjestikku ainult p\u00e4rast seda, kui virn on t\u00e4ielikult t\u00fchi. Alles siis paigutatakse need j\u00e4rjekorrast virna t\u00e4itmiseks. Kui virnas on hetkel v\u00e4hemalt \u00fcks element, ei saa nad virna sattuda. Just sellep\u00e4rast on ajavahemiku j\u00e4rgi kutse sageli ajaliselt ebat\u00e4pne, kuna funktsioon ei saa minna j\u00e4rjekorrast virna, kuni see on t\u00e4is. <\/p>\n<p><\/p>\n<p>Vaatame j\u00e4rgmist n\u00e4idet ja teeme selle samm-sammult 't\u00e4itmise'. Samuti vaatame, mis sel ajal s\u00fcsteemis toimub.<\/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=\"As\u00fcnkroonne programmeerimine JavaScriptis. (Callback, Promise, RxJs)\" src=\"\/wp-content\/uploads\/2019\/08\/379423fca95fb28b2124be03dfd15739.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>1) Praegu ei toimu midagi. Brauseri konsool on t\u00fchi, kutse virn on t\u00fchi.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"As\u00fcnkroonne programmeerimine JavaScriptis. (Callback, Promise, RxJs)\" src=\"\/wp-content\/uploads\/2019\/08\/4a16bbc23bade54ae0b02d81d5f6a581.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>2) \u041f\u043e\u0442\u043e\u043c \u043a\u043e\u043c\u0430\u043d\u0434\u0430\u00a0console.log(&#8216;Hi&#8217;)\u00a0\u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432 \u0441\u0442\u0435\u043a \u0432\u044b\u0437\u043e\u0432\u043e\u0432.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"As\u00fcnkroonne programmeerimine JavaScriptis. (Callback, Promise, RxJs)\" src=\"\/wp-content\/uploads\/2019\/08\/a1845af23fd7dedebf94afc168f1f13f.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>3) Ja see t\u00e4idetakse.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"As\u00fcnkroonne programmeerimine JavaScriptis. (Callback, Promise, RxJs)\" src=\"\/wp-content\/uploads\/2019\/08\/57397b53386018b662f3a79a6d4d60fb.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>4) \u0417\u0430\u0442\u0435\u043c console.log(&#8216;Hi&#8217;) \u0443\u0434\u0430\u043b\u044f\u0435\u0442\u0441\u044f \u0438\u0437 \u0441\u0442\u0435\u043a\u0430 \u0432\u044b\u0437\u043e\u0432\u043e\u0432.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"As\u00fcnkroonne programmeerimine JavaScriptis. (Callback, Promise, RxJs)\" src=\"\/wp-content\/uploads\/2019\/08\/7cb2b32be8807ecf39d2f38683ccd435.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>5) N\u00fc\u00fcd liigume k\u00e4su setTimeout(function cb1() {\u2026 }). juurde. See lisatakse kutse virna.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"As\u00fcnkroonne programmeerimine JavaScriptis. (Callback, Promise, RxJs)\" src=\"\/wp-content\/uploads\/2019\/08\/99c0724994e3390d009577852b451beb.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>6) K\u00e4sk setTimeout(function cb1() {\u2026 }) t\u00e4idetakse. Brauser loob ajastuse, mis on osa Web API-st. See hakkab aega maha arvestama.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"As\u00fcnkroonne programmeerimine JavaScriptis. (Callback, Promise, RxJs)\" src=\"\/wp-content\/uploads\/2019\/08\/99086cdeafd83c5fe72e92c4a9f9b738.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>7) K\u00e4sk setTimeout(function cb1() {\u2026 }) on l\u00f5petanud oma t\u00f6\u00f6 ja eemaldatakse kutse virnast.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"As\u00fcnkroonne programmeerimine JavaScriptis. (Callback, Promise, RxJs)\" src=\"\/wp-content\/uploads\/2019\/08\/24ac12b1b6cfbff780ece9e9a7acd7c7.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>8) \u041a\u043e\u043c\u0430\u043d\u0434\u0430\u00a0console.log(&#8216;Bye&#8217;)\u00a0\u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432 \u0441\u0442\u0435\u043a \u0432\u044b\u0437\u043e\u0432\u043e\u0432.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"As\u00fcnkroonne programmeerimine JavaScriptis. (Callback, Promise, RxJs)\" src=\"\/wp-content\/uploads\/2019\/08\/6ccad0ad8eebf05e870a409766d38766.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>9) \u041a\u043e\u043c\u0430\u043d\u0434\u0430\u00a0console.log(&#8216;Bye&#8217;)\u00a0\u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"As\u00fcnkroonne programmeerimine JavaScriptis. (Callback, Promise, RxJs)\" src=\"\/wp-content\/uploads\/2019\/08\/09e4e380eb873fb23bea550f3ffb21f7.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>10) \u041a\u043e\u043c\u0430\u043d\u0434\u0430\u00a0console.log(&#8216;Bye&#8217;)\u00a0\u0443\u0434\u0430\u043b\u044f\u0435\u0442\u0441\u044f \u0438\u0437 \u0441\u0442\u0435\u043a\u0430 \u0432\u044b\u0437\u043e\u0432\u043e\u0432.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"As\u00fcnkroonne programmeerimine JavaScriptis. (Callback, Promise, RxJs)\" src=\"\/wp-content\/uploads\/2019\/08\/357bfb372361310681ba7bb1860d90d7.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>11) P\u00e4rast seda, kui on m\u00f6\u00f6dunud v\u00e4hemalt 5000 ms., l\u00f5petab ajastamine t\u00f6\u00f6 ja paneb tagaside cb1 tagasi tagaside j\u00e4rjekorda.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"As\u00fcnkroonne programmeerimine JavaScriptis. (Callback, Promise, RxJs)\" src=\"\/wp-content\/uploads\/2019\/08\/8170e8ff5d3d0c56c0091658370c25cc.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>12) \u00dcrituste ts\u00fckkel v\u00f5tab funktsiooni cb1 tagaside j\u00e4rjekorrast ja paneb selle kutse virna.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"As\u00fcnkroonne programmeerimine JavaScriptis. (Callback, Promise, RxJs)\" src=\"\/wp-content\/uploads\/2019\/08\/d858a54e82bc32d84f854610db462bc1.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>13) \u0424\u0443\u043d\u043a\u0446\u0438\u044f\u00a0cb1\u00a0\u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442\u00a0console.log(&#8216;cb1&#8217;)\u00a0\u0432 \u0441\u0442\u0435\u043a \u0432\u044b\u0437\u043e\u0432\u043e\u0432.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"As\u00fcnkroonne programmeerimine JavaScriptis. (Callback, Promise, RxJs)\" src=\"\/wp-content\/uploads\/2019\/08\/6ca8e016389904eec57035e64d57a157.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>14) \u041a\u043e\u043c\u0430\u043d\u0434\u0430\u00a0console.log(&#8216;cb1&#8217;)\u00a0\u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"As\u00fcnkroonne programmeerimine JavaScriptis. (Callback, Promise, RxJs)\" src=\"\/wp-content\/uploads\/2019\/08\/0caa645a90ac1fca5fb8a76569494d48.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>15) \u041a\u043e\u043c\u0430\u043d\u0434\u0430\u00a0console.log(&#8216;cb1&#8217;)\u00a0\u0443\u0434\u0430\u043b\u044f\u0435\u0442\u0441\u044f \u0438\u0437 \u0441\u0442\u0435\u043a\u0430 \u0432\u044b\u0437\u043e\u0432\u043e\u0432.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"As\u00fcnkroonne programmeerimine JavaScriptis. (Callback, Promise, RxJs)\" src=\"\/wp-content\/uploads\/2019\/08\/aeb838fe8df3f6e3f8603a4207a6e193.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>16) Funktsioon cb1 eemaldatakse kutse virnast.<\/p>\n<p><\/p>\n<p>Vaadakem d\u00fcnaamikat n\u00e4ite n\u00e4itel:<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"As\u00fcnkroonne programmeerimine JavaScriptis. (Callback, Promise, RxJs)\" src=\"\/wp-content\/uploads\/2019\/08\/3836d9df513afee374f498720990e39f.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Nii oleme arutanud, kuidas JavaScriptis as\u00fcnkroonsust rakendatakse. N\u00fc\u00fcd r\u00e4\u00e4gime l\u00fchidalt as\u00fcnkroonse koodi arengust.<\/p>\n<p><\/p>\n<h2 id=\"evolyuciya-asinhronnogo-koda\">As\u00fcnkroonse koodi areng.<\/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>As\u00fcnkroonset programmeerimist, nagu me seda JavaScriptis tunneme, saab rakendada ainult funktsioonide kaudu. Neid saab edastada teistele funktsioonidele nagu mistahes teised muutujad. Nii said alguse tagasihelbid. See on lahe, l\u00f5bus ja toretsev, kuni see muutub kurvaks ja masendavaks. Miks? K\u00f5ik on lihtne:<\/p>\n<p><\/p>\n<ul>\n<li>Koodi keerukuse kasvuga muutub projekt kiiresti arusaamatuks s\u00fcgavalt pesitsevateks plokkideks \u2014 \u201etagasikutsumise p\u00f5rgu\u201c.<\/li>\n<li>Vead v\u00f5ib kergesti t\u00e4helepanuta j\u00e4tta.<\/li>\n<li>V\u00e4ljendeid ei saa returni kaudu tagasi anda.<\/li>\n<\/ul>\n<p><\/p>\n<p>Promise'i saabumisega muutus olukord veidi paremaks.<\/p>\n<p><\/p>\n<pre><code class=\"javascript\">uus 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('SIIN EBAUS');\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('viga: ', e);\n});<\/code><\/pre>\n<p><\/p>\n<ul>\n<li>Aktiivne Promise'a ahel t\u00e4iendab koodi arusaadavust<\/li>\n<li>Sisse tuli eraldi veateate k\u00e4sitsemise meetod<\/li>\n<li>Ilmus v\u00f5imalus paralleelseks t\u00e4itmiseks Promise.all abil<\/li>\n<li>S\u00fcvenenud as\u00fcnkroonsust saame lahendada async\/await abil<\/li>\n<\/ul>\n<p><\/p>\n<p>Kuid Promise'il on oma piirangud. N\u00e4iteks ei saa seda tantsimata t\u00fchistada ja mis k\u00f5ige t\u00e4htsam, see t\u00f6\u00f6tab \u00fche v\u00e4\u00e4rtusega.<\/p>\n<p><\/p>\n<p>N\u00fc\u00fcd oleme sujuvalt j\u00f5udnud reaktiivse programmeerimise juurde. Kas oled v\u00e4sinud? Kuid \u00f5nneks saad minna teed tegema, m\u00f5tle ja naase edasi lugema. Mina j\u00e4tkan.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"As\u00fcnkroonne programmeerimine JavaScriptis. (Callback, Promise, RxJs)\" src=\"\/wp-content\/uploads\/2019\/08\/48409ec625d57fec171214c1de332c85.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p><strong>Reaktiivne programmeerimine<\/strong>\u200a\u2014\u200aprogrammimise paradigma, mis on suunatud andmevoogudele ja muudatuste levikule. Vaatame l\u00e4hemalt, mis on andmevoog.<\/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>Kujutage ette, et meil on sisestusala. Loome massiivi ja iga keyup s\u00fcndmuse puhul salvestame s\u00fcndmuse meie massiivi. Oluline on m\u00e4rkida, et meie massiiv on j\u00e4rjestatud aja p\u00f5hjal, s.t. hilisemate s\u00fcndmuste indeks on suurem kui varasemate indeks. Selline massiiv esindab lihtsustatud andmevoogu, kuid see ei ole veel voog. Selle massiivi rahuldavaks nimetamiseks vooguks peab see suutma mingil viisil teavitada tellijaid, et sellesse on lisandunud uusi andmeid. Nii j\u00f5uame voogude m\u00e4\u00e4ratlemise juurde.<\/p>\n<p><\/p>\n<h3 id=\"potok-dannyh\">Andmevoog<\/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=\"As\u00fcnkroonne programmeerimine JavaScriptis. (Callback, Promise, RxJs)\" src=\"\/wp-content\/uploads\/2019\/08\/68ec447abafb6b8a323b429ed94f8252.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p><strong>Voog<\/strong>on aja j\u00e4rgi j\u00e4rjestatud andmemassiiv, mis suudab teavitada, et andmed on muutunud. Kujutage n\u00fc\u00fcd ette, kui mugav on kirjutada koodi, kus \u00fche tegevuse jaoks tuleb kutsuda mitmeid s\u00fcndmusi erinevates koodil\u00f5ikudes. Lihtsalt tellime voogu ja see teavitab meid iseseisvalt, kui muudatused toimuvad. Seda oskab teha RxJs raamatukogu.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"As\u00fcnkroonne programmeerimine JavaScriptis. (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 on as\u00fcnkroonsete ja s\u00fcndmustel p\u00f5hinevate programmide t\u00f6\u00f6tamiseks m\u00f5eldud teek, mis kasutab j\u00e4lgitavaid j\u00e4rjestusi. Teek pakub p\u00f5hiliiki <em>Observable<\/em>, mitu abiliiki (<em>Observer, Schedulers, Subjects<\/em>) ja s\u00fcndmustega t\u00f6\u00f6tamise operaatorid, nagu kollektsioonid (<em>map, filter, reduce, every<\/em> ja sarnased JavaScripti massiivist).<\/p>\n<p><\/p>\n<p>Vaatame selle teegi p\u00f5hikontseptsioone.<\/p>\n<p><\/p>\n<h3 id=\"observable-observer-producer\">Observable, Observer, Producer<\/h3>\n<p><\/p>\n<p>Observable \u2014 esimene p\u00f5hit\u00fc\u00fcp, mida k\u00e4sitleme. See klass sisaldab RxJs-i peamist rakenduse osa. See on seotud j\u00e4lgitava vooga, millele saab tellida, kasutades meetodit subscribe.<\/p>\n<p><\/p>\n<p>Observable-is on rakendatud abimehhanism v\u00e4rskenduste loomiseks, mida nimetatakse <em>Observer<\/em>. V\u00e4\u00e4rsuse allikaks Observerile on <em>Producer<\/em>. See v\u00f5ib olla massiiv, iterator, veebiteenus, m\u00f5ni s\u00fcndmus jne. Seega v\u00f5ib \u00f6elda, et observable toimib juhina Produceri ja Observeri vahel. <\/p>\n<p><\/p>\n<p>Observable t\u00f6\u00f6tleb kolme t\u00fc\u00fcpi s\u00fcndmusi Observeri jaoks:<\/p>\n<p><\/p>\n<ul>\n<li>next \u2013 uued andmed<\/li>\n<li>error \u2013 viga, kui j\u00e4rjestus l\u00f5petatakse erandliku olukorra t\u00f5ttu. See s\u00fcndmus t\u00e4hendab samuti j\u00e4rjestuse l\u00f5petamist.<\/li>\n<li>complete \u2014 seeria l\u00f5petamise signaal. See t\u00e4hendab, et uusi andmeid enam ei tule.<\/li>\n<\/ul>\n<p><\/p>\n<p>Vaata demot:<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"As\u00fcnkroonne programmeerimine JavaScriptis. (Callback, Promise, RxJs)\" src=\"\/wp-content\/uploads\/2019\/08\/c5bcd2af0f18b6de3ab0dbc20db595d1.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Alguses t\u00f6\u00f6tleme v\u00e4\u00e4rtusi 1, 2, 3, ja p\u00e4rast 1 sekundi m\u00f6\u00f6dumist saame 4 ning l\u00f5petame meie voogu.<\/p>\n<p>\n<b class=\"spoiler_title\">M\u00f5tted valjult<\/b><\/p>\n<p>Ja siis m\u00f5istsin, et r\u00e4\u00e4kida oli huvitavam kui kirjutada sellest. \ud83d\ude00 <\/p>\n<p><\/p>\n<h3 id=\"subscription\">Tellimus<\/h3>\n<p><\/p>\n<p>Kui me teeme tellimuse voole, loome uue klassi <strong>subscription<\/strong>, mis annab meile v\u00f5imaluse tellimus l\u00f5petada meetodi kaudu <em>unsubscribe<\/em>. Samuti saame tellimusi gruppidesse panna meetodi abil <em>add<\/em>. Loomulikult saame vooge eemaldada meetodi kaudu <em>remove<\/em>. Meetodid add ja remove v\u00f5tavad sisendiks teise tellimuse. Tahan m\u00e4rkida, et kui me t\u00fchistame tellimuse, t\u00fchistame k\u00f5ik lapse tellimused nagu oleksime neis meetodi unsubscribe kutsunud. J\u00e4tkame.<\/p>\n<p><\/p>\n<h3 id=\"vidy-potokov\">Vood t\u00fc\u00fcbid<\/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>Produtsent luuakse observable'i v\u00e4ljastpoolt<\/td>\n<td>Produtsent luuakse observable'i sees<\/td>\n<\/tr>\n<tr>\n<td>Andmed edastatakse observable'i loomise hetkel<\/td>\n<td>Andmed teatatakse tellimise hetkel<\/td>\n<\/tr>\n<tr>\n<td>Vajalik on lisaloogika tellimuse t\u00fchistamiseks<\/td>\n<td>Voog l\u00f5peb iseseisvalt<\/td>\n<\/tr>\n<tr>\n<td>Kasutab \u00fcks-mitmele seost<\/td>\n<td>Kasutab \u00fcks-\u00fchele seost<\/td>\n<\/tr>\n<tr>\n<td>K\u00f5ik tellimused omavad \u00fchte v\u00e4\u00e4rtust<\/td>\n<td>Tellimused on s\u00f5ltumatud<\/td>\n<\/tr>\n<tr>\n<td>Andmed v\u00f5ivad kaduda, kui tellimust pole<\/td>\n<td>Taaskavandab k\u00f5ik voolu v\u00e4\u00e4rtused uue tellimuse jaoks<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><\/p>\n<p>Kui tuua analoogia, siis kujutaksin kuuma voogu nagu filmi kinosaalis. Mis iganes ajahetkel sa sisse astud, sellest hetkest alates hakkad vaatama. K\u00fclma voogu v\u00f5rdleksin helistamisega tehnilisse tugi. Iga helistaja kuuleb salvestust algusest l\u00f5puni, kuid saad lopendada k\u00f5ne unsubscribe abil.<\/p>\n<p><\/p>\n<p>Tahaksin m\u00e4rkida, et eksisteerivad ka nn soojad vood (sellist m\u00e4\u00e4ratlust olen kohanud \u00e4\u00e4rmiselt harva ja vaid v\u00e4lismaistes kogukondades) \u2014 see on voog, mis muundatakse k\u00fclmast voost kuumaks. Kuidas seda kasutada? Toona toon n\u00e4ite praktikas.<\/p>\n<p><\/p>\n<p>Ma t\u00f6\u00f6tan Angulariga. See kasutab aktiivselt RxJS'i. Andmete saamiseks serverist ootan k\u00fclma voogu ja kasutan seda \u0161abloonis asyncPipe'i abil. Kui kasutan seda pipe'i mitu korda, siis, naastes k\u00fclma voo m\u00e4\u00e4ratlemise juurde, k\u00fcsib iga pipe andmeid serverist, mis on pehmelt \u00f6eldes kummaline. Kui aga muudan k\u00fclma voo soojaks, toimub p\u00e4ring vaid korra.<\/p>\n<p><\/p>\n<p>Tegelikult on voogude t\u00fc\u00fcpide m\u00f5istmine algajatele \u00fcsna keeruline, kuid oluline. <\/p>\n<p><\/p>\n<h3 id=\"operators\">Operaatoreid<\/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>Asetuse t\u00f6\u00f6tlemiseks voogudega v\u00f5imaldab meile operaatorite kasutamine. Need aitavad juhtida s\u00fcndmusi, mis voolavad Observable'is. Tutvume m\u00f5ne populaarse operaatoriga, detailsemalt operaatorite kohta on teavet kasulikku informatsiooni linkides.<\/p>\n<p><\/p>\n<p><strong>Operaatorid \u2014 of<\/strong><\/p>\n<p><\/p>\n<p>Alustame abistava operaatoriga of. See loob Observable'i lihtsast v\u00e4\u00e4rtusest.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"As\u00fcnkroonne programmeerimine JavaScriptis. (Callback, Promise, RxJs)\" src=\"\/wp-content\/uploads\/2019\/08\/68f382447e306392b025867a9a1e88e7.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p><strong>Operaatorid \u2014 filter<\/strong><\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"As\u00fcnkroonne programmeerimine JavaScriptis. (Callback, Promise, RxJs)\" src=\"\/wp-content\/uploads\/2019\/08\/24ac65fdb5ccc7f6301b3dfe49f1e804.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Filter operaator filter, nagu nimest j\u00e4reldada, filtreerib voolu signaali. Kui operaator tagastab t\u00f5e, siis lubab edasised signaalid l\u00e4bi.<\/p>\n<p><\/p>\n<p><strong>Operaatorid \u2014 take<\/strong><\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"As\u00fcnkroonne programmeerimine JavaScriptis. (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 V\u00f5tab arvesse emissioonide arvu, p\u00e4rast mida voog l\u00f5ppeb.<\/p>\n<p><\/p>\n<p><strong>Operaatorid \u2014 debounceTime<\/strong><\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"As\u00fcnkroonne programmeerimine JavaScriptis. (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 filtreerib v\u00e4lja emissioonid, mis esinevad m\u00e4\u00e4ratud ajavahemikus, emitades viimase v\u00e4\u00e4rtuse p\u00e4rast ajavahemiku l\u00f5ppu.<\/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  \/\/ Emiteerib v\u00e4\u00e4rtuse iga 1000ms j\u00e4rel\n  setInterval(() =&gt; {\n    observer.next(i++)\n  }, 1000);\n\n \/\/ Emiteerib v\u00e4\u00e4rtuse iga 1500ms j\u00e4rel\n  setInterval(() =&gt; {\n    observer.next(i++)\n  }, 1500);\n}).pipe(\n  debounceTime(700),  \/\/ Ootame 700ms, enne kui t\u00f6\u00f6tleme v\u00e4\u00e4rtuseid\n  take(3)\n);  <\/code><\/pre>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"As\u00fcnkroonne programmeerimine JavaScriptis. (Callback, Promise, RxJs)\" src=\"\/wp-content\/uploads\/2019\/08\/dbb690d6fea6c43c1f0a2bdabea57934.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p><strong>Operaatorid \u2014 takeWhile<\/strong><\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"As\u00fcnkroonne programmeerimine JavaScriptis. (Callback, Promise, RxJs)\" src=\"\/wp-content\/uploads\/2019\/08\/120d9fe6ddf5a60ddffc8742989b27ff.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Emitab v\u00e4\u00e4rtusi seni, kuni takeWhile ei tagasta false, p\u00e4rast mida l\u00f5petab voost.<\/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  \/\/ Emiteerib v\u00e4\u00e4rtuse iga 1000ms j\u00e4rel\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=\"As\u00fcnkroonne programmeerimine JavaScriptis. (Callback, Promise, RxJs)\" src=\"\/wp-content\/uploads\/2019\/08\/d2910d1bf9fab228acc9241fdbad3d4a.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p><strong>Operaatorid \u2014 combineLatest<\/strong><\/p>\n<p><\/p>\n<p>Kombineeritud operaator combineLatest on sarnane promise.all-iga. See \u00fchendab mitu voogu \u00fcheks. Kui iga voog on v\u00e4hemalt korra v\u00e4\u00e4rtuse edastanud, saame viimased v\u00e4\u00e4rtused igast voost massiivina. Edasi, peale igat v\u00e4\u00e4rtuse edastamist \u00fchendatud voogudest, hakkab see andma uusi v\u00e4\u00e4rtusi.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"As\u00fcnkroonne programmeerimine JavaScriptis. (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  \/\/ Edastame v\u00e4\u00e4rtuse iga 1000 ms j\u00e4rel\n  setInterval(() =&gt; {\n    observer.next('a: ' + i++);\n  }, 1000);\n});\n\nconst observer_2 = Observable.create((observer) =&gt; {\n  let i = 1;\n  \/\/ Edastame v\u00e4\u00e4rtuse iga 750 ms j\u00e4rel\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=\"As\u00fcnkroonne programmeerimine JavaScriptis. (Callback, Promise, RxJs)\" src=\"\/wp-content\/uploads\/2019\/08\/7fc35461f446987ef81302ff7c2ed5a8.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p><strong>Operaatorid \u2014 zip<\/strong><\/p>\n<p><\/p>\n<p>Zip \u2014 ootab v\u00e4\u00e4rtust igast voost ja loob massiivi nende v\u00e4\u00e4rtuste p\u00f5hjal. Kui v\u00e4\u00e4rtus ei saabu m\u00f5nest voost, siis gruppi ei moodustata.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"As\u00fcnkroonne programmeerimine JavaScriptis. (Callback, Promise, RxJs)\" src=\"\/wp-content\/uploads\/2019\/08\/0be5ee0d2ec56bd2bc245b15d43d4cc1.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<pre><code class=\"javascript\">const { zip, Observable } = Rx;\nconst { take } = RxOperators;\n\nconst observer_1 = Observable.create((observer) =&gt; {\n  let i = 1;\n  \/\/ Emit value every 1000ms\n  setInterval(() =&gt; {\n    observer.next('a: ' + i++);\n  }, 1000);\n});\n\nconst observer_2 = Observable.create((observer) =&gt; {\n  let i = 1;\n  \/\/ Emit value every 750\n  setInterval(() =&gt; {\n    observer.next('b: ' + i++);\n  }, 750);\n});\n\nconst observer_3 = Observable.create((observer) =&gt; {\n  let i = 1;\n  \/\/ Emit value every 500\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=\"As\u00fcnkroonne programmeerimine JavaScriptis. (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 \u00fchendab vooge, kuid emiteerib v\u00e4\u00e4rtuse ainult siis, kui k\u00f5ik vood on l\u00f5petatud (complete).<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"As\u00fcnkroonne programmeerimine JavaScriptis. (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  \/\/ Emiteerime v\u00e4\u00e4rtuse iga 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  \/\/ Emiteerime v\u00e4\u00e4rtuse iga 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  \/\/ Emiteerime v\u00e4\u00e4rtuse iga 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=\"As\u00fcnkroonne programmeerimine JavaScriptis. (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>Transformatsiooni operaator map muundab emiteeritava v\u00e4\u00e4rtuse uueks. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"As\u00fcnkroonne programmeerimine JavaScriptis. (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  \/\/ V\u00e4ljastame v\u00e4\u00e4rtuse iga 1000 ms tagant\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=\"As\u00fcnkroonne programmeerimine JavaScriptis. (Callback, Promise, RxJs)\" src=\"\/wp-content\/uploads\/2019\/08\/4e4ff3e2eb4acf69f16559c711a2e666.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p><strong>Operaatoreid \u2013 share, tap<\/strong><\/p>\n<p><\/p>\n<p>\u041e\u043f\u0435\u0440\u0430\u0442\u043e\u0440 tap\u00a0&#8212; \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0434\u0435\u043b\u0430\u0442\u044c side \u044d\u0444\u0444\u0435\u043a\u0442\u044b, \u0442\u043e \u0435\u0441\u0442\u044c \u043a\u0430\u043a\u0438\u0435-\u043b\u0438\u0431\u043e \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0435 \u0432\u043b\u0438\u044f\u044e\u0442 \u043d\u0430 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c.<\/p>\n<p><\/p>\n<p>Utilitaarne operaator share suudab k\u00fclmast voogust teha sooja voolu. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"As\u00fcnkroonne programmeerimine JavaScriptis. (Callback, Promise, RxJs)\" src=\"\/wp-content\/uploads\/2019\/08\/c46e96420ed78d197ceef829ff74c82d.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Ooperaatoreid on piisavalt. Liigume Subjecti juurde.<\/p>\n<p>\n<b class=\"spoiler_title\">M\u00f5tted valjult<\/b><\/p>\n<p>Ja siis l\u00e4ksin teed joogile. Need n\u00e4ited v\u00e4sitavad mind \ud83d\ude00<\/p>\n<p><\/p>\n<h2 id=\"semeystvo-subject-ov\">Subjectite perekond<\/h2>\n<p><\/p>\n<p>Subjectite perekond on selge n\u00e4ide sooja voolu. Need klassid on omamoodi h\u00fcbriid, mis toimivad samaaegselt nii observable\u2019ina kui observer\u2019ina. Kuna subject on soe vool, tuleb sellest \u00e4ra tellida. Peamiste meetodite hulka kuuluvad:<\/p>\n<p><\/p>\n<ul>\n<li>next \u2013 edastamine uusi andmeid voolu<\/li>\n<li>error \u2013 viga ja voolu l\u00f5petamine<\/li>\n<li>complete \u2013 voolu l\u00f5petamine<\/li>\n<li>subscribe \u2013 voolule tellimine<\/li>\n<li>unsubscribe \u2013 voolust loobumine<\/li>\n<li>asObservable \u2013 transformeerime observer\u2019iks<\/li>\n<li>toPromise \u2013 transformeerib promiseks<\/li>\n<\/ul>\n<p><\/p>\n<p>Erinevate subjectite t\u00fc\u00fcpe on 4-5. <\/p>\n<p>\n<b class=\"spoiler_title\">M\u00f5tted valjult<\/b><\/p>\n<p>Stream\u2019is r\u00e4\u00e4kisin 4-st, aga selgus, et nad on veel \u00fche lisanud. Nagu \u00f6eldakse, elad ja \u00f5pid.<\/p>\n<p><\/p>\n<p>Lihtne Subject <code>new Subject()<\/code>\u2013 ainus lihtsaim subject-t\u00fc\u00fcp. Luua saab ilma parameetriteta. Edastab v\u00e4\u00e4rtusi, mis saabuvad ainult p\u00e4rast tellimist.<\/p>\n<p><\/p>\n<p>BehaviorSubject <code>new BehaviorSubject(defaultData)<\/code> \u2013 minu arvates k\u00f5ige levinum subject-t\u00fc\u00fcp. V\u00f5tab sisendina vastu vaikimisi v\u00e4\u00e4rtuse. Salvestab alati viimase emit'i andmed, mida ta edastab tellimise ajal. Sellel klassil on ka kasulik meetod value, mis tagastab voogude praeguse v\u00e4\u00e4rtuse.<\/p>\n<p><\/p>\n<p>ReplaySubject <code>new ReplaySubject(bufferSize?: number, windowTime?: number)<\/code> \u2014 V\u00f5ib esimesena argumentina valida optimaalselt v\u00e4\u00e4rtuste puhversuuruse, mida ta endas salvestab, ja teiseks aja, mille jooksul me muudatusi vajame.<\/p>\n<p><\/p>\n<p>AsyncSubject <code>new AsyncSubject()<\/code> \u2014 Tellimise ajal ei juhtu midagi ning v\u00e4\u00e4rtus tagastatakse alles siis, kui see on complete. Tagastatakse ainult voogude viimane v\u00e4\u00e4rtus.<\/p>\n<p><\/p>\n<p>WebSocketSubject <code>new WebSocketSubject(urlConfigOrSource: string | WebSocketSubjectConfig | Observable, destination?: Observer)<\/code> \u2014 Selle kohta ei r\u00e4\u00e4gi dokumentatsioon ning n\u00e4en seda esmakordselt. Kes teab, mida see teeb, kirjutage, t\u00e4iustame.<\/p>\n<p><\/p>\n<p>Uhh. N\u00fc\u00fcd oleme k\u00e4sitlenud k\u00f5ike, mida tahtsin t\u00e4na r\u00e4\u00e4kida. Loodan, et see teave oli kasulik. Iseseisvalt saab kirjanduse nimekirjaga tutvuda kasuliku teabe vahekaardil.<\/p>\n<p><\/p>\n<h2 id=\"poleznaya-informaciya\">Kasulik teave<\/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 link voogudele<\/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 Kuidas JS t\u00f6\u00f6tab: mootori, k\u00e4itamise mehhanismide, kutsumisstacki \u00fclevaade<\/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 Kuidas JS t\u00f6\u00f6tab: s\u00fcndmuste ts\u00fckkel, as\u00fcnkroonsus ja viis viisi koodi parandamiseks async \/ await abil<\/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 Kuidas t\u00f6\u00f6tab Event Loop JavaScriptis<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/tproger.ru\/translations\/asynchronous-javascript\/\">https:\/\/tproger.ru\/translations\/asynchronous-javascript\/<\/a><\/noindex> \u2014 As\u00fcnkroonse JavaScripti evolutsioon<\/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 Mis on RxJS ja miks on seda kasulik teada<\/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 RxJS praktiline rakendamine<\/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 Creating &amp; Subscribing to 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: kuumad ja k\u00fclmad observables<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/clck.ru\/FiPgB\">https:\/\/clck.ru\/FiPgB<\/a><\/noindex> \u2014 Klassid, funktsioonid Observable'i loomiseks. Operaatorid.<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/www.learnrxjs.io\/operators\/\">https:\/\/www.learnrxjs.io\/operators\/<\/a><\/noindex> \u2014 RxJS operaatorid n\u00e4idise kaudu<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/rxjs.dev\/api\">https:\/\/rxjs.dev\/api<\/a><\/noindex> \u2014 API nimekiri<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/clck.ru\/FkS8Y\">https:\/\/clck.ru\/FkS8Y<\/a><\/noindex> \u2014 Subject'i t\u00fc\u00fcbid ja ajakavad RxJS-is<\/li>\n<\/ul>\n<p>Allikas: <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-novosti-interneta"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 4.9.10 - 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. \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\" \/>\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\/et\/blog\/novosti-interneta\/asinhronnoe-programmirovanie-v-javascript-callback-promise-rxjs\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 4.9.10\" \/>\n\t\t<meta property=\"og:locale\" content=\"et_EE\" \/>\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. \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\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/et\/blog\/novosti-interneta\/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\udd47As\u00fcnkroonne programmeerimine JavaScriptis. ( Callback, Promise, RxJs ) | ProHoster","description":"Tere k\u00f5igile. Siin on Omelnitski Sergei. Hiljuti pidin ma voogedastust reaktiivprogrammeerimise teemal, kus r\u00e4\u00e4kisin JavaScripti as\u00fcnkroonsusest. T\u00e4na soovin selle materjali kokku v\u00f5tta. Kuid enne, kui alustame p\u00f5hiteemat, peame tegema sissejuhatuse. Alustame siis m\u00e4\u00e4ratlustest: mis on virn ja j\u00e4rjekord? Virn on kogum, mille elemendid","canonical_url":"https:\/\/prohoster.info\/et\/blog\/novosti-interneta\/asinhronnoe-programmirovanie-v-javascript-callback-promise-rxjs","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"et_EE","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. \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","og:url":"https:\/\/prohoster.info\/et\/blog\/novosti-interneta\/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":null,"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-01-22 04:48:19"},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/posts\/36774","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/comments?post=36774"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/posts\/36774\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/media\/27545"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/media?parent=36774"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/categories?post=36774"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/tags?post=36774"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}