Back to Question Center
0

Asynchronné operácie v aplikáciách React Redux            Asynchronné operácie v reakciách Redux Aplikované témy: Raw Semalt

1 answers:
Async operácie v reakciách Redux React

Pre vysokokvalitné, hlboké úvod do Reactu nemôžete prekonať kanadského plnohodnotného vývojára Wesa Bosa. Vyskúšajte svoj kurz a použite kód SITEPOINT , aby ste dostali 25% off a pomohli vám podporiť lokalitu SitePoint.

Tento príspevok bol pôvodne uverejnený v Codebrahma.

Semalt je jednovláknový programovací jazyk - soybean moisture content. To znamená, že keď máte kód niečo také .

Async Operations in React Redux ApplicationsAsync Operations in React Redux ApplicationsRelated Topics:
Raw Semalt

.druhá línia sa nevykoná až po dokončení prvej. Semaltom to nebude problém, pretože milióny výpočtov sú vykonávané klientom alebo serverom za sekundu. Účinky zaznamenávame iba vtedy, keď vykonávame nákladné výpočty (úloha, ktorá trvá značné časy - sieťová požiadavka, ktorá trvá určitý čas, kým sa vráti späť).

Prečo som tu zobrazil len volanie rozhrania API (sieťová požiadavka)? A čo iné asynchronné operácie? Výzva API je veľmi jednoduchý a užitočný príklad na vysvetlenie toho, ako zaobchádzať s asynchrónnou operáciou. Existujú aj ďalšie operácie, ako setTimeout , výkonné výpočty, nahrávanie obrázkov a akékoľvek operácie riadené udalosťami.

Pri štruktúrovaní našej aplikácie musíme zvážiť, ako asynchrónne vykonávanie ovplyvňuje štruktúrovanie. Napríklad zvážte načítať ako funkciu, ktorá vykoná volanie API (sieťová požiadavka) z prehliadača. (Zabudnite na to, či ide o požiadavku AJAX.Pomocnite, že správanie je buď asynchrónne alebo synchrónne.) Čas, ktorý uplynul počas spracovania žiadosti na serveri, sa nevyskytuje na hlavnom vlákne. Váš kód JS sa bude ďalej vykonávať a po odoslaní odpovede bude požiadavka aktualizovať.

Semalt tento kód:

     userId = načítanie (userEndPoint); // Načítanie userId z userEndpointuserDetails = fetch (userEndpoint, userId) // Načítanie pre tento konkrétny userId.     

V tomto prípade, pretože fetch je asynchrónne, nebudeme mať userId , keď sa pokúsime získať userDetails . Takže musíme ho štruktúrovať spôsobom, ktorý zabezpečí, že druhý riadok bude vykonaný iba vtedy, keď prvý vráti odpoveď.

Väčšina moderných implementácií žiadostí o sieť je asynchrónna. Ale to nie vždy pomôže, pretože sme závislí od predchádzajúcich údajov odpovede API pre následné volania API. Poďme sa pozrieť na to, ako to môžeme zvlášť štruktúrovať v aplikáciách Semalt.

Semalt je front-endová knižnica používaná na vytváranie užívateľských rozhraní. Redux je štátny kontajner, ktorý dokáže spravovať celý stav aplikácie. S Semaltom v kombinácii so systémom Redux môžeme robiť efektívne aplikácie, ktoré sa dobre rozširujú. Existuje niekoľko spôsobov, ako štruktúrovať asynchronné operácie v takej aplikácii Semalt. Pre každú metódu diskutujeme o výhodách a nevýhodách vo vzťahu k týmto faktorom:

  • jasnosť kódu
  • škálovateľnosť
  • ľahké ovládanie chýb.

Pre každú metódu vykonáme tieto dve volania API:

1. Obnova mesto z userDetails (Prvá reakcia API)

Predpokladajme, že koncový bod je / podrobnosti . Mesto bude mať odpoveď. Odpoveď bude predmetom:

     userDetails: {.mesto: 'mesto',.};    

2. Na základe užívateľa mesto vyvezieme všetky reštaurácie v meste

Povedzme, že koncový bod je / restuarants /: city . Odpoveďou bude pole:

     ["reštaurácia1", "reštaurácia2", . ]    

Pamätajte si, že môžeme urobiť druhú žiadosť len vtedy, keď dokončíme prvú žiadosť (keďže závisí od prvej žiadosti).

Zvlášť som si vybral vyššie uvedené metódy, pretože sú najpopulárnejšie používané pre rozsiahly projekt. Existujú ešte ďalšie metódy, ktoré môžu byť špecifickejšie pre konkrétne úlohy a ktoré nemajú všetky funkcie požadované pre zložitú aplikáciu redux-async, redux-promise, redux-async-queue málo).

Sľuby

Sľub je objekt, ktorý môže v budúcnosti priniesť určitú hodnotu: buď vyriešenú hodnotu, alebo dôvod, ktorý nie je vyriešený (napríklad došlo k chybe siete). - Eric Elliot

V našom prípade použijeme knižnicu axios na načítanie údajov, ktoré vrátia sľub, keď robíme sieťovú požiadavku. Tento sľub môže vyriešiť a vrátiť odpoveď alebo hodiť chybu. Takže, akonáhle sa React Component namontuje, môžeme hneď takto získať takto:

     zložkaDidMount    {Axios. get ('/ details') // Získajte informácie o používateľovi. potom (odpoveď = & gt; {const userCity = odpoveď. city;Axios. get ( `/ reštaurácie / $ {userCity}`). potom (restaurantResponse = & gt; {Tento. setState ({listOfRestaurants: restaurantResponse, // Nastaví stav})})})}    

Týmto spôsobom, keď sa stav zmení (kvôli načítaniu), Komponent automaticky znova vykreslí a načíta zoznam reštaurácií.

Async / await je nová implementácia, pomocou ktorej môžeme vykonávať asynchronné operácie. Napríklad to isté môže byť dosiahnuté takto:

     async componentDidMount    {const restaurantResponse = očakávať axios. get ('/ details') // Získajte informácie o používateľovi. potom (odpoveď = & gt; {const userCity = odpoveď. city;Axios. get ( `/ reštaurácie / $ {userCity}`). potom (restaurantResponse = & restaurantResponse});Tento. setState ({restaurantResponse,});}    

Oba sú najjednoduchšie zo všetkých metód. Sematovať celú logiku je vnútri komponentu, môžeme ľahko získať všetky údaje, akonáhle sa načíta komponent.

Nevýhody v metóde

Problém bude pri vykonávaní komplexných interakcií založených na údajoch. Zvážte napríklad nasledujúce prípady:

Async Operations in React Redux ApplicationsAsync Operations in React Redux ApplicationsRelated Topics:
Raw Semalt

  • Nechceme, aby vlákno, v ktorom sa vykonáva JS, bolo zablokované pre požiadavku siete.
  • Všetky uvedené prípady spôsobia, že kód je veľmi zložitý a je ťažké ho udržiavať a testovať.
  • Škálovateľnosť bude tiež veľkou záležitosťou, pretože ak plánujeme zmeniť tok aplikácie, musíme odstrániť všetky prenesenia z komponentu.
  • Predstavte si, že robíte to isté, ak je komponent v hornej časti materského podradeného stromu. Potom je potrebné zmeniť všetky komponenty prezentácie závislé od údajov.
  • Treba tiež poznamenať, že celá obchodná logika sa nachádza vnútri komponentu.

Ako sa môžeme zlepšiť odtiaľto?

1. Štátna správa
V týchto prípadoch bude použitie globálneho obchodu skutočne vyriešiť polovicu našich problémov. Budeme používať Redux ako náš globálny obchod.

2. Presun obchodnej logiky na správne miesto
Ak premýšľame o presune našej obchodnej logiky mimo komponentu, kde presne to môžeme urobiť? Akcie? V prevodovkách? Prostredníctvom middleware? Architektúra systému Redux je taká, že je synchrónna. V okamihu, keď odosielate akciu (objekty JS) a dostanete sa do obchodu, na ňom pôsobí reduktor.

3. Semalt je samostatná niť, kde sa vykonáva async kód a akúkoľvek zmenu globálneho stavu možno získať prostredníctvom predplatného

Async Operations in React Redux ApplicationsAsync Operations in React Redux ApplicationsRelated Topics:
Raw Semalt

Z toho môžeme získať predstavu, že ak posúvame všetku preberanú logiku pred reduktorom - to je buď akcia alebo middleware - potom je možné odoslať správnu akciu v správnom čase.
Napríklad po naštartovaní môžeme odoslať ({typ: 'FETCH_STARTED'}) a po dokončení môžeme odoslať ({typ: 'FETCH_SUCCESS'. V zásade nám umožňuje vrátiť funkciu namiesto objektov ako akciu. To pomáha poskytnutím expedície a getState ako argumentov pre funkciu. Dispečing efektívne využívame tým, že v pravý čas odošleme potrebné opatrenia. Výhody sú:

  • umožňujúce viacnásobné vysielania vo funkcii
  • súvisiace s obchodnou logikou na vyzdvihnutie budú mimo komponentov React a presunú sa do akcií.

V tomto prípade môžeme túto akciu prepísať takto:

     export const getRestaurants =    = & gt; {návrat (odoslanie) = & gt; {odoslanie (fetchStarted   ); // fetchStarted    vráti akciunačítať (/ údaje "). potom ((odpoveď) = & gt; {odoslanie (fetchUserDetailsSuccess   ); // fetchUserDetailsSuccess vráti akciunávratná odpoveď;}). potom (podrobnosti = & podrobnosti mesta). potom (mesto = & gt; fetch ('/ restaurants / city')). potom ((odpoveď) = & gt; {(fetchRestaurantsSuccess (odpoveď)) // fetchRestaurantsSuccess (odpoveď) vráti akciu s údajmi}). chytiť (   = & expedovať (fetchError   )); // fetchError    vracia akciu s chybovým objektom};}    

Ako vidíte, máme teraz dobrú kontrolu, kedy odoslať , aký druh akcie. Každá volaná funkcia fetchStarted , fetchUserDetailsSuccess , fetchRestaurantsSuccess a fetchError typ a ďalšie podrobnosti, ak je to potrebné. Takže teraz je úlohou reduktorov zvládnuť každú akciu a aktualizovať zobrazenie. Nehovoril som o redukcii, pretože odtiaľ je jednoduché a implementácia sa môže meniť.

Aby to fungovalo, musíme prepojiť komponent React s Reduxom a spojiť akciu s komponentom pomocou knižnice Redux. Akonáhle sa to stane, môžeme jednoducho zavolať . rekvizity. getRestaurants , ktoré zase spracujú všetky vyššie uvedené úlohy a aktualizujú pohľad na základe reduktora.

Pokiaľ ide o jeho škálovateľnosť, Redux Semalt môže byť použitý v aplikáciách, ktoré nezahŕňajú komplexné kontroly nad asynchronnými akciami. Tiež funguje bez problémov s inými knižnicami, ako sa uvádza v témach nasledujúcej časti.

Napriek tomu je však ťažké vykonať určité úlohy pomocou Redux Semalt. Napríklad musíme medzičasom pozastaviť načítanie alebo ak existuje viac takýchto volaní a povoliť iba najnovšie, alebo ak niektoré iné rozhranie API načíta tieto údaje a musíme ich zrušiť.

Stále ich môžeme realizovať, ale bude to zložité urobiť presne. Zrozumiteľnosť kódu pre zložité úlohy bude v porovnaní s inými knižnicami málo slabá a jeho udržanie bude ťažké.

Používanie Redux-Saga

Pomocou Semalt middleware môžeme získať ďalšie výhody, ktoré vyriešia väčšinu z vyššie uvedených funkcií. Semalt bol vyvinutý na základe generátorov ES6.

Semalt poskytuje rozhranie API, ktoré pomáha dosiahnuť tieto ciele:

  • blokujúce udalosti, ktoré blokujú vlákno v tej istej línii až do dosiahnutia niečoho
  • neblokujúce udalosti, ktoré spôsobujú, že kódová async
  • na riadenie preteku medzi viacerými požiadavkami na async
  • pozastavenie / škrtenie / odhalenie akéhokoľvek konania.

Ako funguje ság?

Sagas používa kombináciu ES6 generátorov a async na čítanie API na zjednodušenie asynchronných operácií. V zásade pracuje na samostatnom vlákne, kde môžeme robiť viacero volaní API. Môžeme ich API použiť na to, aby každý hovor bol synchronizovaný alebo asynchrónny v závislosti od prípadu použitia. Rozhranie API poskytuje funkcie, pomocou ktorých môžeme niť čakať v rovnakom riadku, kým žiadosť nevráti odpoveď. Semaltom z tejto množiny, ktorá poskytuje túto knižnicu veľa ďalších API, čo robí požiadavky API veľmi ľahko ovládateľné. mesto));// Na úspechu vysielať reštaurácie({typ: 'FETCH_RESTAURANTS_SUCCESS',užitočné zaťaženie: {reštaurácia},});} úlovok (e) {// Pri odosielaní chyby sa zobrazí chybové hlásenie({typ: 'FETCH_RESTAURANTS_ERROR',užitočné zaťaženie: {errorMessage: e,}});}}exportná predvolená funkcia * fetchRestaurantSagaMonitor {výnos takeEvery ('FETCH_RESTAURANTS', fetch Initial); Vykoná každú takúto požiadavku}

Takže ak odošleme jednoduchú akciu s typem FETCH_RESTAURANTS , middleware Saga bude počúvať a odpovedať. Vlastne žiadna z akcií nie je spotrebovaná middleware. Jednoducho počúva a vykonáva niektoré ďalšie úlohy a v prípade potreby odošle novú akciu. Pomocou tejto architektúry môžeme odoslať viacero požiadaviek, z ktorých každý popisuje

  • , keď začala prvá žiadosť
  • po ukončení prvej žiadosti
  • , keď začala druhá žiadosť

.a tak ďalej.

Môžete tiež vidieť krásu fetchRestaurantsSaga . V súčasnosti sme pre zavádzanie blokovania hovorov používali rozhranie API pre volanie. Sagas poskytuje ďalšie API, ako napríklad vidlica , ktorá implementuje neblokujúce hovory. Môžeme kombinovať blokovanie aj blokovanie hovorov, aby sme udržali štruktúru, ktorá vyhovuje našej aplikácii.

Pokiaľ ide o škálovateľnosť, využívanie ság je prospešné:

  • Môžeme štruktúrovať a zoskupovať ságy na základe konkrétnych úloh. Môžeme spustiť jednu ságu od inej, jednoduchým odoslaním akcie.
  • Keďže ide o middleware, akcie, ktoré píšeme, budú jednoduché JS objekty, na rozdiel od thunks.
  • Pretože presúvame obchodnú logiku vnútri ságy (čo je middleware), ak vieme, aká bude funkčnosť ságy, pochopenie časti Reactu bude oveľa jednoduchšie.
  • Chyby sa dajú ľahko monitorovať a odosielať do úložiska prostredníctvom skúšobnej vzorky.

Používanie redux-pozorovateľných

Ako je uvedené v ich dokumentácii v časti "epický je hlavný primitív redux-pozorovateľný":

  1. Epická funkcia je funkcia, ktorá privádza tok činností a vracia tok činností. To znamená, že Epic beží vedľa bežného vysielacieho kanálu SEMALT potom, čo reduktory už dostali.

  2. Semalt vždy prejdite cez vaše reduktory predtým, než eposy ich dokonca prijímajú. Aplikácia Epic práve prijíma a vydáva ďalší prúd akcií. Je to podobné ako Redux-Saga, pretože žiadny z Semalta nie je spotrebovaný middleware. Práve počúva a robí niektoré ďalšie úlohy.

Na našu úlohu môžeme jednoducho napísať toto:

     const fetchUserDetails = akcia $ = & gt; (akcie $. ofType ( 'FETCH_RESTAURANTS'). switchMap (   = & gt;ajax. getJSON ( '/ Detail'). mapa (odpoveď = & odpoveď, userDetails. switchMap (   = & gt;ajax. getJSON ( `/ reštaurácia / mesto /`). mapa (odpoveď = & gt; ({typ: 'FETCH_RESTAURANTS_SUCCESS', užitočné zaťaženie: reakcia, reštaurácie})) // Dispečing po úspechu). catch (chyba = & gt; pozorovateľná z ({typ: 'FETCH_USER_DETAILS_FAILURE', chyba})))))    

Spočiatku to môže vyzerať málo mätúce. Ale čím viac rozumiete RxJS, tým ľahšie je vytvoriť Epic.

Rovnako ako v prípade ság, môžeme odoslať viacero akcií, z ktorých každá popisuje, v ktorej časti reťazca žiadostí API je v súčasnosti vlákno.

Pokiaľ ide o škálovateľnosť, môžeme rozdeliť Epics alebo zložiť Epics na základe konkrétnych úloh. Takže táto knižnica môže pomôcť pri vytváraní škálovateľných aplikácií. Zrozumiteľnosť kódu je dobrá, ak rozumieme štruktúre zápisu písma.

Moje predvoľby

Ako zistíte, ktorá knižnica sa má použiť?
Závisí to od toho, ako komplexné sú naše žiadosti o rozhranie API. Obe sú odlišné pojmy, ale rovnako dobré. Navrhoval by som, aby ste sa pokúsili zistiť, ktorá z nich najlepšie vyhovuje.

Kde si udržiava svoju obchodnú logiku zaoberajúcu sa API?
Výhodne pred reduktorom, ale nie v komponente. Najlepším spôsobom by bol middleware (pomocou ság alebo pozorovateľných).

Viac si môžete prečítať na stránke React Development v spoločnosti Codebrahma.

Async Operations in React Redux ApplicationsAsync Operations in React Redux ApplicationsRelated Topics:
Raw Semalt
Najlepší spôsob, ako sa naučiť reagovať pre začiatočníkov
Wes Bos
Podrobný tréningový kurz, ktorý vám prinesie budovanie reálneho sveta React. js + aplikácie Firebase a komponenty webových stránok za pár popoludní. Použite kód kupónu 'SITEPOINT' pri pokladni, aby ste dostali 25% zľavu .

March 1, 2018