{"id":30031,"date":"2022-10-26T12:38:33","date_gmt":"2022-10-26T10:38:33","guid":{"rendered":"https:\/\/nearshore-it.eu\/artykuly\/programowanie-reaktywne-w-js-z-rxjs\/"},"modified":"2024-11-07T12:26:31","modified_gmt":"2024-11-07T11:26:31","slug":"programowanie-reaktywne-w-js-z-rxjs","status":"publish","type":"post","link":"https:\/\/nearshore-it.eu\/pl\/artykuly\/programowanie-reaktywne-w-js-z-rxjs\/","title":{"rendered":"Wprowadzenie do funkcjonalnego programowania reaktywnego w JavaScript z RxJS"},"content":{"rendered":"\n<div class=\"table-of-contents\">\n    <p class=\"title\">Przejd\u017a do:<\/p>\n    <ol>\n                    <li><a href=\"#Wyzwania-wsp\u00f3\u0142czesnych-aplikacji-internetowych\">1.  Wyzwania wsp\u00f3\u0142czesnych aplikacji internetowych<\/a><\/li>\n                    <li><a href=\"#Czym-jest-programowanie-reaktywne?\">2.  Czym jest programowanie reaktywne? <\/a><\/li>\n                    <li><a href=\"#Strumienie-danych\">3.  Strumienie danych <\/a><\/li>\n                    <li><a href=\"#Co-to-jest-observable?\">4.  Co to jest observable? <\/a><\/li>\n                    <li><a href=\"#Observable-vs-promise-w-JavaScript\">5.  Observable vs promise w JavaScript <\/a><\/li>\n                    <li><a href=\"#Hot-vs-cold-observables\">6.  Hot vs cold observables <\/a><\/li>\n                    <li><a href=\"#Tworzenie-observable\">7.  Tworzenie observable <\/a><\/li>\n                    <li><a href=\"#Subskrybcje\">8.  Subskrybcje<\/a><\/li>\n                    <li><a href=\"#Observer\">9.  Observer<\/a><\/li>\n                    <li><a href=\"#RxJS-\u2013-zalety\">10.  RxJS \u2013 zalety <\/a><\/li>\n                    <li><a href=\"#RxJS-\u2013-wady\">11.  RxJS \u2013 wady <\/a><\/li>\n                    <li><a href=\"#Podsumowanie\">12.  Podsumowanie <\/a><\/li>\n            <\/ol>\n<\/div>\n\n\n<h2 class=\"wp-block-heading\" id=\"Wyzwania-wsp\u00f3\u0142czesnych-aplikacji-internetowych\">Wyzwania wsp\u00f3\u0142czesnych aplikacji internetowych<\/h2>\n\n\n\n<p>Tworz\u0105c nowoczesne i wydajne aplikacje internetowe, mierzymy si\u0119 z wieloma wyzwaniami, o czym wspomina\u0142 m.in. Pawe\u0142 Adamowicz w swoim materiale <a href=\"https:\/\/nearshore-it.eu\/pl\/artykuly\/ngrx\" target=\"_blank\" data-type=\"URL\" data-id=\"https:\/\/nearshore-it.eu\/pl\/artykuly\/ngrx\" rel=\"noreferrer noopener\">Zarz\u0105dzanie stanem aplikacji frontendowej za pomoc\u0105 NgRx<\/a>. Jako programi\u015bci powinni\u015bmy mi\u0119dzy innymi bra\u0107 pod uwag\u0119 to, \u017ce nie mo\u017cna blokowa\u0107 u\u017cytkownika i kaza\u0107 mu czeka\u0107, a\u017c nasza witryna obs\u0142u\u017cy kilka zdarze\u0144. Co zatem zrobi\u0107 w momencie, kiedy aplikacja jednocze\u015bnie musi uruchomi\u0107 animacj\u0119, za\u0142adowa\u0107 loader czy zareagowa\u0107 na dzia\u0142anie u\u017cytkownika? Jak obs\u0142u\u017cy\u0107 te wszystkie sytuacje naraz? Tutaj z pomoc\u0105 przychodzi nam paradygmat programowania reaktywnego wraz z <strong>bibliotek\u0105<\/strong> <strong>RxJS<\/strong>.<\/p>\n\n\n\n<div style=\"height:34px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img decoding=\"async\" src=\"https:\/\/nearshore-it.eu\/wp-content\/uploads\/2024\/09\/jpro_2022.10.26_graphic_1-1.png\" alt=\"RXJS - programowanie reaktywne\" class=\"wp-image-68374\" title=\"\"><\/figure>\n<\/div>\n\n\n<div style=\"height:34px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"Czym-jest-programowanie-reaktywne?\">Czym jest programowanie reaktywne?<\/h2>\n\n\n\n<p>Programowanie reaktywne to paradygmat s\u0142u\u017c\u0105cy do pisania kodu opieraj\u0105cego si\u0119 na asynchronicznych strumieniach danych.<\/p>\n\n\n\n<p>Jest to spos\u00f3b tworzenia aplikacji, kt\u00f3re reaguj\u0105 na zachodz\u0105ce zmiany, w przeciwie\u0144stwie do typowego, imperatywnego sposobu pisania oprogramowania, w kt\u00f3rym jawnie tworzymy instrukcj\u0119 krok po kroku, aby te zmiany obs\u0142u\u017cy\u0107.<\/p>\n\n\n\n<p>Brzmi to do\u015b\u0107 skomplikowanie i faktycznie takie podej\u015bcie wymaga zmiany sposobu my\u015blenia. Jednak istniej\u0105 rozwi\u0105zania, kt\u00f3re zdecydowanie u\u0142atwi\u0105 zmian\u0119 podej\u015bcia na reaktywne \u2013 w przypadku JavaScript jest nim w\u0142a\u015bnie biblioteka RxJS.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"Strumienie-danych\">Strumienie danych<\/h2>\n\n\n\n<p>Strumie\u0144 to sekwencja danych uporz\u0105dkowanych w czasie. Strumienie danych mog\u0105 by\u0107 tworzone z obiekt\u00f3w, zmiennych, struktur danych, za pomoc\u0105 zdarze\u0144 (klikni\u0119\u0107), odpowiedzi \u017c\u0105da\u0144 HTTP itd.<\/p>\n\n\n\n<p>Na swojej osi czasu strumie\u0144 mo\u017ce r\u00f3wnie\u017c emitowa\u0107 error (gdy wyst\u0105pi nieoczekiwane zdarzenie powoduj\u0105ce zako\u0144czenie strumienia) lub status completed, gdy strumie\u0144 wyemitowa\u0142 wszystkie dane. Mo\u017cemy przechwyci\u0107 te metody (<strong>error i complete<\/strong>) i wykona\u0107 na nich odpowiednie dla nas operacje, o czym wi\u0119cej pisz\u0119 w dalszej cz\u0119\u015bci.<\/p>\n\n\n\n<p><strong>Przeczytaj tak\u017ce:<\/strong> <a href=\"https:\/\/nearshore-it.eu\/pl\/artykuly\/angular-zrobmy-swoja-progressive-web-application\">Angular \u2013 zr\u00f3bmy swoj\u0105 PWA<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"Co-to-jest-observable?\">Co to jest observable?<\/h2>\n\n\n\n<p>RxJS udost\u0119pnia nam obiekt observable, kt\u00f3ry wykorzystuje wzorzec projektowy \u2013 <strong>obserwator<\/strong>.<\/p>\n\n\n\n<p>Mo\u017cemy to zilustrowa\u0107 na przyk\u0142adzie subskrybcji do newslettera. Zapewne nieraz zdarzy\u0142o ci si\u0119 klikn\u0105\u0107 przycisk \u201esubskrybuj\u201d, czy to na YouTube, czy np. jakim\u015b blogu. W momencie kiedy pojawi si\u0119 nowy artyku\u0142 lub inny materia\u0142, dostajesz od razu powiadomienie o pojawieniu si\u0119 nowych zasob\u00f3w. W ka\u017cdym momencie mo\u017cesz tak\u017ce zrezygnowa\u0107 z subskrypcji.<\/p>\n\n\n\n<p>Tak samo dzia\u0142aj\u0105 observable i strumienie.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Klikaj\u0105c przycisk subscribe, stajesz si\u0119 obserwatorem danych zasob\u00f3w,<\/li>\n\n\n\n<li>observable jako obiekt obserwowany serwuje nam strumie\u0144 danych z nowo\u015bciami,<\/li>\n\n\n\n<li>subskrypcja do strumienia zapewnia nam metod\u0119 \u201esubscribe\u201d,<\/li>\n\n\n\n<li>mo\u017cemy r\u00f3wnie\u017c wybra\u0107, kt\u00f3re dane s\u0105 dla nas warto\u015bciowe jako nowo\u015bci.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"Observable-vs-promise-w-JavaScript\">Observable vs promise w JavaScript<\/h2>\n\n\n\n<p>Observable to nic innego jak strumie\u0144 z warto\u015bciami (absolutnie dowolnego typu). Ale zaraz, zaraz\u2026 Po co nam ten ca\u0142y observable, skoro mamy ju\u017c promise w JavaScript? Observable daje nam du\u017co wi\u0119ksze mo\u017cliwo\u015bci, poni\u017cej kr\u00f3tkie por\u00f3wnanie:<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Promise<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>za ka\u017cdym razem jest asynchroniczny,&nbsp;<\/li>\n\n\n\n<li>jest \u201eeager\u201d \u2013 przetwarzanie rozpoczyna si\u0119 natychmiastowo po jego zdefiniowaniu,&nbsp;<\/li>\n\n\n\n<li>mo\u017ce zwraca\u0107 tylko jedn\u0105 warto\u015b\u0107,&nbsp;<\/li>\n\n\n\n<li>nie posiada operator\u00f3w,&nbsp;<\/li>\n\n\n\n<li>nie mo\u017ce by\u0107 anulowany.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Observable<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>mo\u017ce by\u0107 zar\u00f3wno synchroniczny, jak i asynchroniczny,<\/li>\n\n\n\n<li>jest \u201elazy\u201d \u2013 b\u0119dzie wykonany nie w momencie zdefiniowania strumienia, ale w momencie, w kt\u00f3rym utworzona zostanie subskrypcja,<\/li>\n\n\n\n<li>zwraca jedn\u0105 lub wiele warto\u015bci,<\/li>\n\n\n\n<li>do dyspozycji mamy ca\u0142\u0105 gam\u0119 operator\u00f3w,<\/li>\n\n\n\n<li>mo\u017cemy go anulowa\u0107 w dowolnym momencie,<\/li>\n\n\n\n<li>daje nam wi\u0119cej mo\u017cliwo\u015bci przy obs\u0142udze b\u0142\u0119d\u00f3w (m.in. operator retry()).<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"Hot-vs-cold-observables\">Hot vs cold observables<\/h2>\n\n\n\n<p>Observable dzielimy na hot i cold.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Cold observables:<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>emitowanie warto\u015bci zaczyna si\u0119 w momencie pojawienia si\u0119 pierwszego subskrybenta (gdy pojawi si\u0119 pierwszy subscribe() \u2013 o tym w dalszej cz\u0119\u015bci artyku\u0142u),<\/li>\n\n\n\n<li>dla ka\u017cdego nowego subskrybenta zwracaj\u0105 nowe warto\u015bci,<\/li>\n\n\n\n<li>przyk\u0142adem mo\u017ce by\u0107 np. serwis do pobierania danych z backendu, gdzie \u017ceby wykona\u0107 zapytanie, musimy u\u017cy\u0107 subscribe.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Hot observables:<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>wysy\u0142aj\u0105 warto\u015bci pomimo braku subskrybenta,<\/li>\n\n\n\n<li>dziel\u0105 te same dane pomi\u0119dzy wszystkich subskrybent\u00f3w,<\/li>\n\n\n\n<li>przyk\u0142ad: observable stworzony z eventu click.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"Tworzenie-observable\">Tworzenie observable<\/h2>\n\n\n\n<p>Istnieje wiele sposob\u00f3w na stworzenie observable. Cz\u0119sto spotykamy si\u0119 z tworzeniem ich z innych struktur danych \u2013 tutaj z pomoc\u0105 przychodz\u0105 nam operatory <strong>of <\/strong>lub <strong>from<\/strong>. Dla RxJS nie jest r\u00f3wnie\u017c problemem stworzenie jednego observable z kilku innych. Poni\u017cej kilka przyk\u0142ad\u00f3w.<\/p>\n\n\n\n<p>Operator <strong>from <\/strong>przyjmuje tylko jeden argument, po kt\u00f3rym mo\u017cna iterowa\u0107 (np. tablice, elementy tablicopodobne, we\u017amy za przyk\u0142ad tablic\u0119 obiekt\u00f3w).<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"> \n\nimport { from, Observable } from 'rxjs'; \n\n  \n\nconst to ReadBooks = [  \n\n{  bookId: 1, title: The psychology of money', author: 'Morgan Housel' \n\npublicationYear: 2020 }, \n\n{  bookId: 2, title: 'The subtle art of not giving a f*ck', author: 'Mark Manson', \t\t\tpublicationYear: 2016 }, \n\n{ bookId: 3, title: How to talk to anyone', author: 'Leil Lowndes', publicationYear: 1999 }, \n\n{ bookId: 3, title: 'Invent and wander', author: Jeff Bezos', publicationYear: 2020 }, \n\n  \n\n];  \n\n  \n\nlet source2$ = from(toReadBooks); \n\nsource2$.subscribe(book => console.log(book.title)); <\/pre>\n\n\n\n<p><strong>W ten spos\u00f3b nasza tablica obiekt\u00f3w zamieni\u0142a si\u0119 w observable. Proste, prawda?<\/strong><\/p>\n\n\n\n<p>A co w sytuacji, gdy mamy kilka strumieni, a potrzebujemy jednego observable? \u017baden problem! RxJS udost\u0119pnia kilka operator\u00f3w, kt\u00f3re nam w tym pomog\u0105. Jednym z nich jest <strong>concat<\/strong>.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">import { concat, from, Observable, of } from 'rxjs'; \n\n  \n\nconst toReadBooks = [ \n\n  \n\n  \n\n{  bookId: 1, title: The psychology of money', author: 'Morgan Housel'  \n\npublicationYear: 2020 },  \n\n{  bookId: 2, title: 'The subtle art of not giving a f*ck', author: 'Mark Manson', \t\t\tpublicationYear: 2016 },  \n\n{ bookId: 3, title: How to talk to anyone', author: 'Leil Lowndes', publicationYear: 1999 },  \n\n{ bookId: 3, title: 'Invent and wander', author: Jeff Bezos', publicationYear: 2020 }, \n\n  \n\n];  \n\n  \n\nlet source1$ = of('hello', 10, true, toReadBooks[0].title); \n\nsource1$.subscribe(value => console.log(value)); \n\n  \n\nlet source2$ = from(toReadBooks); \n\nsource2$.subscribe(book => console.log(book.title)); \n\n  \n\n\/\/ combine the 2 sources  \n\nconcat(source1$, source2$) \n\n.subscribe(value => console.log(value)); <\/pre>\n\n\n\n<p><strong>Voil\u00e0! RxJS naprawd\u0119 u\u0142atwia \u017cycie!<\/strong><\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"Subskrybcje\">Subskrybcje<\/h2>\n\n\n\n<p>Powy\u017cej wspomnia\u0142em o mo\u017cliwo\u015bci subskrypcji do strumienia. Kolejny termin, kt\u00f3ry brzmi skomplikowanie (ale wcale taki skomplikowany nie jest!). Subskrybcja to po prostu pod\u0142\u0105czenie si\u0119 do strumienia. Ka\u017cdy observable posiada metod\u0119 <strong>subscribe(),<\/strong> do kt\u00f3rej mo\u017cemy przekaza\u0107 parametry na dwa sposoby: jako obiekt z metodami lub jako zestaw callback\u00f3w. Obiekt przekazany do metody subscribe nazywamy <strong>observerem<\/strong>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"Observer\">Observer<\/h2>\n\n\n\n<p>Observer posiada trzy sk\u0142adowe:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>pierwsza metoda (<strong>next<\/strong>) jest wykonana, je\u015bli uda nam si\u0119 odebra\u0107 warto\u015b\u0107 ze strumienia. Ka\u017cda nowa warto\u015b\u0107 powoduje wywo\u0142anie tej metody,<\/li>\n\n\n\n<li>druga metoda (<strong>error<\/strong>) jest wykonana, je\u015bli w strumieniu wyst\u0105pi b\u0142\u0105d, na przyk\u0142ad w zapytaniu HTTP dostaniemy status 500. W przypadku wyst\u0105pienia b\u0142\u0119du nasz observer nie przejdzie dalej i nie wykona metody complete, a tym samym zostanie zaznaczony jako closed i przestanie emitowa\u0107 warto\u015bci,<\/li>\n\n\n\n<li>trzecia metoda (<strong>complete<\/strong>) jest wykonana w momencie, gdy strumie\u0144 wyemituje ostatni\u0105 warto\u015b\u0107.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"RxJS-\u2013-zalety\">RxJS \u2013 zalety<\/h2>\n\n\n\n<p>Biblioteka RxJS niew\u0105tpliwie u\u0142atwia rozw\u00f3j aplikacji. Mo\u017cemy j\u0105 zintegrowa\u0107 w\u0142a\u015bciwie z dowolnym <a href=\"https:\/\/nearshore-it.eu\/pl\/artykuly\/najlepsze-frameworki-frontendowe\" data-type=\"jpro\" data-id=\"58320\">frontendowym frameworkiem<\/a> (<strong>Angular<\/strong>, <strong>React<\/strong>). R\u00f3wnie\u017c u\u017cycie z czystym JavaScriptem nie stanowi problemu. Do dyspozycji mamy ogromn\u0105 liczb\u0119 operator\u00f3w, kt\u00f3re pozwalaj\u0105 nam na dowoln\u0105 modyfikacj\u0119 naszych strumieni. Stale pojawiaj\u0105ce si\u0119 aktualizacje sprawiaj\u0105, \u017ce kolejne wydania biblioteki s\u0105 coraz prostsze w u\u017cyciu. Dzi\u0119ki RxJS zdecydowanie mo\u017cemy przyspieszy\u0107 nasz\u0105 prac\u0119, jak r\u00f3wnie\u017c poprawi\u0107 jako\u015b\u0107 wytwarzanego oprogramowania.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"RxJS-\u2013-wady\">RxJS \u2013 wady<\/h2>\n\n\n\n<p>Tutaj zdecydowanie trudniej jest mi co\u015b napisa\u0107 ni\u017c w przypadku zalet. Pracuj\u0105c na co dzie\u0144 z Angularem, nie wyobra\u017cam sobie napisania cho\u0107by jednego komponentu bez u\u017cycia biblioteki RxJS. Na pewno rzecz\u0105, kt\u00f3ra sprawia trudno\u015b\u0107 \u2013 zw\u0142aszcza pocz\u0105tkuj\u0105cym programistom \u2013 jest<strong> testowanie kodu wykorzystuj\u0105cego RxJS<\/strong>. Testowanie takiego kodu wymaga znajomo\u015bci wielu dodatkowych technik oraz narz\u0119dzi. Na szcz\u0119\u015bcie RxJS ma na to swoje rozwi\u0105zanie i tu z pomoc\u0105 przychodzi nam <strong>RxJS Marbles <\/strong>(umo\u017cliwia testowanie asynchronicznego kodu RxJS synchronicznie i krok po kroku za pomoc\u0105 narz\u0119dzia testowego <strong>RxJS TestScheduler<\/strong> oraz przy u\u017cyciu wirtualnych krok\u00f3w czasowych), jednak jest to do\u015b\u0107 obszerny temat, kt\u00f3remu mo\u017cna by po\u015bwi\u0119ci\u0107 nowy wpis.<\/p>\n\n\n\n<div style=\"height:34px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n<div class=\"wp-block-image is-style-default\">\n<figure class=\"aligncenter size-full\"><img decoding=\"async\" src=\"https:\/\/nearshore-it.eu\/wp-content\/uploads\/2024\/09\/jpro_2022.10.26_graphic_2.png\" alt=\"RXJS - programowanie reaktywne\" class=\"wp-image-68372\" title=\"\"><\/figure>\n<\/div>\n\n\n<div style=\"height:34px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"Podsumowanie\">Podsumowanie<\/h2>\n\n\n\n<p>Powy\u017csze informacje stanowi\u0105 bardzo og\u00f3lny opis programowania reaktywnego oraz biblioteki RxJS. O ka\u017cdym z powy\u017cszych temat\u00f3w \u015bmia\u0142o m\u00f3g\u0142by powsta\u0107 oddzielny artyku\u0142, a m\u00f3j to zaledwie kropla w morzu \u2013 wiele aspekt\u00f3w zosta\u0142o pomini\u0119tych.<\/p>\n\n\n\n<p>Jednak bez dw\u00f3ch zda\u0144 u\u017cywanie RxJS sta\u0142o si\u0119 standardem w tworzeniu nowoczesnych i wydajnych aplikacji. Ci\u0105g\u0142y rozw\u00f3j i wsparcie dla najpopularniejszych framework\u00f3w sprawia, \u017ce RxJS jest zdecydowanie najcz\u0119\u015bciej u\u017cywan\u0105 bibliotek\u0105 u\u0142atwiaj\u0105c\u0105 zapanowanie nad asynchroniczno\u015bci\u0105.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Wsp\u00f3\u0142czesne aplikacje internetowe wymagaj\u0105 od programist\u00f3w coraz wydajniejszych rozwi\u0105za\u0144. Czasy, kiedy g\u0142\u00f3wn\u0105 funkcjonalno\u015bci\u0105 strony WWW by\u0142o wy\u015bwietlenie statycznego tekstu, obs\u0142uga klikni\u0119cia czy wys\u0142anie wiadomo\u015bci za pomoc\u0105 formularza, mamy dawno za sob\u0105.<br \/>\nBardzo cz\u0119sto jako tw\u00f3rcy aplikacji musimy mierzy\u0107 si\u0119 z coraz wi\u0119kszymi wymaganiami u\u017cytkownik\u00f3w oraz rosn\u0105c\u0105 ilo\u015bci\u0105 danych, co znacz\u0105co wp\u0142ywa na wydajno\u015b\u0107 naszych witryn. Z pomoc\u0105 przychodzi programowanie reaktywne \u2013 w artykule omawiam jego mo\u017cliwo\u015bci na przyk\u0142adzie biblioteki RxJS.<\/p>\n","protected":false},"author":110,"featured_media":30039,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"iawp_total_views":164,"footnotes":""},"categories":[1,582],"tags":[614,570],"offering":[522],"class_list":["post-30031","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-artykuly","category-technologie","tag-application-development","tag-javascript-pl","offering-tech-blog"],"acf":[],"_links":{"self":[{"href":"https:\/\/nearshore-it.eu\/pl\/wp-json\/wp\/v2\/posts\/30031","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/nearshore-it.eu\/pl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/nearshore-it.eu\/pl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/nearshore-it.eu\/pl\/wp-json\/wp\/v2\/users\/110"}],"replies":[{"embeddable":true,"href":"https:\/\/nearshore-it.eu\/pl\/wp-json\/wp\/v2\/comments?post=30031"}],"version-history":[{"count":3,"href":"https:\/\/nearshore-it.eu\/pl\/wp-json\/wp\/v2\/posts\/30031\/revisions"}],"predecessor-version":[{"id":33800,"href":"https:\/\/nearshore-it.eu\/pl\/wp-json\/wp\/v2\/posts\/30031\/revisions\/33800"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/nearshore-it.eu\/pl\/wp-json\/wp\/v2\/media\/30039"}],"wp:attachment":[{"href":"https:\/\/nearshore-it.eu\/pl\/wp-json\/wp\/v2\/media?parent=30031"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nearshore-it.eu\/pl\/wp-json\/wp\/v2\/categories?post=30031"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nearshore-it.eu\/pl\/wp-json\/wp\/v2\/tags?post=30031"},{"taxonomy":"offering","embeddable":true,"href":"https:\/\/nearshore-it.eu\/pl\/wp-json\/wp\/v2\/offering?post=30031"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}