Back to Question Center
0

Asynkotoiminnot React Redux -ohjelmissa            Async-toiminnot React Redux -ohjelmissaToimattomat aiheet: Raw Semalt

1 answers:
Async-toiminnot React Redux -ohjelmissa

Reactin laadukkaan ja syvällisen käyttöönoton lisäksi et voi ohittaa kanadalaista täyspinoa kehittäjä Wes Bosia. Kokeile kurssia täällä ja käytä koodia SITEPOINT saadaksesi 25% pois ja avustamaan SitePointia.

Tämä viesti lähetettiin alunperin Codebrahmaan.

Semalt on yksikierreinen ohjelmointikieli - certificate of fitness examination answers. Eli kun sinulla on jotain tällaista koodia .

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

.toista riviä ei saada suoritetuksi, kunnes ensimmäinen on valmis. Epäonnistuminen ei ole ongelma, koska asiakkaat tai palvelimet suorittavat miljoonia laskutoimituksia toisessa. Huomaamme vaikutukset vain silloin, kun suoritamme kalliin laskelman (tehtävä, joka tekee huomattavan kauan - verkkopyyntö, joka kestää jonkin aikaa palata takaisin).

Miksi näytin vain API-puhelun (verkkopyyntö) täällä? Entä muut asynkotoiminnot? API-puhelu on hyvin yksinkertainen ja hyödyllinen esimerkki tapahtuvan asynkronisen toiminnan käsittelemiseksi. On olemassa muita toimintoja, kuten setTimeout , suorituskykyiset raskaslaskenta, kuvien lataus ja mahdolliset tapahtumavetoiset operaatiot.

Sovelluksen jäsentämisen aikana meidän on tarkasteltava, miten asynkroninen toteutus vaikuttaa jäsentämiseen. Esimerkiksi, fetch funktiona, joka suorittaa API-puhelun (verkkopyynnön) selaimesta. (Unohda, jos se on AJAX-pyyntö. Ajattele käyttäytymistä joko asynkronisena tai synkronisena luonteena.) Suoran viestin aikana tapahtunut aika, jonka aikana pyyntö käsitellään palvelimella, ei tapahdu. Niinpä JS-koodisi pysyy suoritettuna, ja kun pyyntö palauttaa vastauksen, se päivittää langan.

Korvataan tämä koodi:

     userId = hakeminen (userEndPoint); // Hae userId käyttäjältäEndpointuserDetails = noutaa (userEndpoint, userId) // Hae kyseiselle käyttäjälle.     
userDetails , kun fetch on asynkroninen, emme saa userId: tä . Joten meidän on rakennettava se siten, että toinen rivi toteutuu vasta, kun ensimmäinen palauttaa vastauksen.

Verkkopyyntöjen nykyaikaisimmat toteutukset ovat asynkronisia. Mutta tämä ei aina auta, koska riippuu aiemmista API-vastaustiedoista myöhemmille API-puheluille. Katsotaanpa, kuinka erityisesti voimme rakentaa tämän Semalt-sovelluksissa.

Semalt on etupään kirjasto, jota käytetään käyttöliittymien luomiseen. Redux on valtion kontti, joka pystyy hallitsemaan sovelluksen koko tilaa. Semaltin ja Reduxin kanssa voimme tehdä tehokkaita sovelluksia, jotka skaalaavat hyvin. On olemassa useita tapoja rakentaa asynketoimintoja tällaisessa Semalt-sovelluksessa. Kutakin menetelmää varten keskustellaan etuja ja haittoja suhteessa näihin tekijöihin:

  • koodin selkeys
  • skaalautuvuus
  • virheenkäsittelyn helppous.

Jokaiselle menetelmälle suoritetaan nämä kaksi API-puhelua:

userDetails (Ensimmäinen API-vastaus)

Oletetaan, että päätepiste on / yksityiskohdat . Se on kaupungin vastaus. Vastaus on tarkoitus:

     userDetails: {.kaupunki: 'city',.};    

2. Käyttäjän kaupungin perusteella noudamme kaikki ravintolat kaupungissa

Sanotaan, että päätepiste on / restuarants /: city . Vastaus on taulukko:

     ['ravintola1', 'ravintola2', . ]    

Muista, että voimme tehdä toisen pyynnön vasta, kun lopetamme ensimmäisen (koska se riippuu ensimmäisestä pyynnöstä).

Erityisesti olen valinnut edellä mainitut menetelmät, koska ne ovat yleisimmin käytetty laajamittaiseen hankkeeseen. On vielä olemassa muita menetelmiä, jotka voivat olla tarkempia tiettyihin tehtäviin ja joilla ei ole kaikkia monimutkaisen sovelluksen tarvitsemia ominaisuuksia ( redux-async, redux-lupaus, redux-asynk-jono harvat).

Lupaukset

Lupaus on kohde, joka voi tuottaa yhden arvon jonkin aikaa tulevaisuudessa: joko ratkaistu arvo tai syy siihen, että sitä ei ole ratkaistu (esimerkiksi verkkovirhe tapahtui). - Eric Elliot

Meidän tapauksessamme käytämme axios-kirjastoa noutamaan tietoja, jotka palauttavat lupauksen, kun teemme verkkopyynnön. Tämä lupaus voi ratkaista ja palauttaa vastauksen tai heittää virheen. Joten, kun React Component kiinnitetään, voimme heti noutaa näin:

     komponenttiDidMount    {Axios. get ('/ details') // Hanki käyttäjän tiedot. sitten (vastaus = & gt; {const userCity = vastaus. kaupunki;Axios. saada ( `/ ravintoloita / $ {userCity}`). sitten (restaurantResponse = & gt; {Tämä. setState ({listOfRestaurants: restaurantResponse, // Asettaa tilan})})})}    

Tällä tavoin, kun tila muuttuu (nouduksen vuoksi), Komponentti palauttaa automaattisesti ja lataa ravintolistasi.

Async / await on uusi toteutus, jolla voimme tehdä asynkotoimintaa. Esimerkiksi sama asia voidaan saavuttaa tällä tavalla:

     asynkomponenttiDidMount    {const restaurantResponse = Odota axios. get ('/ details') // Hanki käyttäjän tiedot. sitten (vastaus = & gt; {const userCity = vastaus. kaupunki;Axios. saada ( `/ ravintoloita / $ {userCity}`). sitten (restaurantResponse = & gt; restaurantResponse});Tämä. setState ({restaurantResponse,});}    

Molemmat ovat kaikkein yksinkertaisimpia. Epäonnistuu koko logiikan sisällä komponentissa, voimme helposti hakea kaikki tiedot kun komponentti latautuu.

Menetelmän puutteet

Ongelmana on tehdä monimutkaisia ​​vuorovaikutuksia tietojen perusteella. Ottakaa esimerkiksi huomioon seuraavat tapaukset:

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

  • Emme halua, että lanka, johon JS on suoritettu, on estetty verkkopyynnön vuoksi.
  • Kaikissa edellä mainituissa tapauksissa koodi on erittäin monimutkainen ja vaikea ylläpitää ja testata.
  • Skaalautuvuus on myös iso ongelma, sillä jos aiomme muuttaa sovelluksen virtaa, meidän on poistettava kaikki komponentit.
  • Kuvittele samaa, jos komponentti on emolevyn puun yläosassa. Sitten meidän on vaihdettava kaikki datapohjaiset esittelykomponentit.
  • Huomaa myös, että koko liiketoiminnan logiikka on komponentin sisällä.

Miten voimme parantaa täältä?

1. Valtionhallinto
Näissä tapauksissa maailmanlaajuinen myymälä käyttää itse asiassa puolet ongelmistamme. Käytämme Reduxia maailmanlaajuisena myymälämme.

2. Liikkeen logiikan siirtäminen oikeaan paikkaan
Jos ajattelemme liikkumasta liiketoimintalogiikasta komponentin ulkopuolelle, niin missä me voimme tehdä niin? Toimissa? Vähennysventtiileissä? Via middleware? Reduxin arkkitehtuuri on sellainen, että se on luonteeltaan synkroninen. Kun lähetät toiminnon (JS-esineet) ja se saapuu myymälään, vähennyslaite vaikuttaa siihen.

3. Semalt on erillinen lanka, jossa asynkoodi suoritetaan ja mikä tahansa muutos globaaliin tilaan voidaan hakea tilauksen kautta

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

Tästä voimme saada käsityksen, että jos siirrämme kaiken haun logiikan ennen vähennyslaskua - joka on joko toiminto tai väliohjelmisto - niin on mahdollista lähettää oikea toiminta oikeaan aikaan.
Esimerkiksi, kun nouto alkaa, voimme lähettää ({type: 'FETCH_STARTED'}) ja kun se on valmis, voimme lähettää ({type: 'FETCH_SUCCESS'}) . Periaatteessa voimme palauttaa toiminnon kohteiden sijaan toiminnoksi. Tämä auttaa tarjoamalla lähetyksen ja getState funktion argumentteiksi. Käytämme lähettämistä tehokkaasti lähettämällä tarvittavat toimenpiteet oikeaan aikaan. Edut ovat:

  • , joka sallii useita lähetyksiä toiminnon
  • , joka liittyy liiketoimintalogiikkaan haulle, on React-komponenttien ulkopuolella ja siirretty toimintoihin.

Meidän tapauksessamme voimme kirjoittaa uudelleen näin:

     vienti const getRestaurants =    = & gt; {palautus (lähetys) = & gt; {lähettäminen (fetchStarted   ); // fetchStarted    palauttaa toiminnonnouto ( '/ yksityiskohdat). sitten ((vastaus) = & gt; {lähettäminen (fetchUserDetailsSuccess   ); // fetchUserDetailsSuccess palauttaa toiminnonpaluureaktio;}). sitten (yksityiskohdat = & gt; yksityiskohdat, kaupunki). sitten (kaupunki = & gt; hae ("/ ravintolat / kaupunki")). sitten ((vastaus) = & gt; {lähetys (fetchRestaurantsSuccess (vastaus)) // fetchRestaurantsSuccess (vastaus) palauttaa toiminnon tietojen kanssa}). catch (   = & gt; lähetys (fetchError   )); // fetchError    palauttaa toiminnon, jossa on virhekoodi};}    

Kuten näette, meillä on nyt hyvä kontrolli siitä, milloin lähetetään millaista toimintaa. Jokainen toiminto, kuten fetchStarted , fetchUserDetailsSuccess , fetchRestaurantsSuccess ja fetchError lähettää normaalin JavaScript-objektin tyyppi ja lisätiedot tarvittaessa. Joten nyt se on vähentäjien tehtävä käsitellä jokaista toimintaa ja päivittää näkymä. En ole keskustellut vähennysventtiilistä, koska se on yksinkertaista täältä ja toteutus saattaa vaihdella.

Jotta tämä toimisi, meidän on yhdistettävä React-komponentti Reduxin ja sitouduttava toimintaan komponentilla Redux-kirjaston avulla. Kun tämä on tehty, voimme yksinkertaisesti soittaa tähän. rekvisiitta. getRestaurants , joka vuorostaan ​​käsittelee kaikki edellä mainitut tehtävät ja päivittää näkymän vähennysventtiilillä.

Skaalautuvuuteensa Redux Semaltia voidaan käyttää sovelluksissa, joissa ei ole monimutkaisia ​​valvontatoimia asynkotoiminnoissa. Lisäksi se toimii saumattomasti muiden kirjastojen kanssa, kuten seuraavassa osiossa käsitellään.

Mutta silti on vähän vaikeata tehdä tiettyjä tehtäviä Redux Semaltin avulla. Esimerkiksi meidän on keskeytettävä hakutoiminto kesken tai kun on useita tällaisia ​​puheluja ja sallimme vain viimeisimmän tai jos joku muu sovellusliittymä hakee nämä tiedot ja meidän on peruutettava tämä.

Voimme vielä toteuttaa niitä, mutta se on hyvin monimutkaista tehdä tarkalleen. Koodin selkeys monimutkaisten tehtävien suhteen on vähäistä verrattuna muihin kirjastoihin ja ylläpito on vaikeaa.

Redux-Sagan käyttö

Semalt-väliohjelmiston avulla voimme saada lisäetuja, jotka ratkaisevat useimmat yllä mainituista toiminnoista. Semalt kehitettiin ES6-generaattoreiden perusteella.

Semalt tarjoaa API: n, joka auttaa saavuttamaan seuraavat:

  • estävät tapahtumat, jotka estävät langan samassa linjassa, kunnes saavutetaan jotain
  • ei-estäviä tapahtumia, jotka muodostavat koodin async
  • käsittelevä kilpailu useiden asynkopyyntöjen välillä
  • keskeyttää / kuristaa / kumota kaikki toiminnot.

Miten sagat toimivat?

Sagas käyttää ES6-generaattorien ja async odottaa API-sovellusten yhdistelmää yksinkertaistaa asynkäyttöä. Se pohjimmiltaan tekee sen työstä erillisellä langalla, jossa voimme tehdä useita API-puheluita. Voimme käyttää sovellusliittymäämme, jotta kukin puhelu synkronoituu tai asynkronisesti riippuen käyttötapauksesta. API tarjoaa toimintoja, joiden avulla voimme tehdä langan odottavan samalta linjalta, kunnes pyyntö palauttaa vastauksen. Tästä huolimatta kirjastossa on paljon muita API: n tarjoamia sovellusliittymiä, joten API-pyyntöjä on helppo käsitellä. kaupunki));// Menestyksestä lähetetään ravintolattuotto ({tyyppi: 'FETCH_RESTAURANTS_SUCCESS',hyötykuorma: {ravintolat},});} saalis (e) {// Virheilmoituksen lähettäminen virhesanomatuotto ({tyyppi: 'FETCH_RESTAURANTS_ERROR',hyötykuorma: {errorMessage: e,}});}}viedä oletusfunktio * fetchRestaurantSagaMonitor {tuotto takeEvery ("FETCH_RESTAURANTS", fetchInitial); // ottaa vastaan ​​kaikki tällaiset pyynnöt}

Joten jos lähetämme yksinkertaisen toimenpiteen tyyppiä FETCH_RESTAURANTS , Saga-väliohjelmisto kuuntelee ja vastaa. Itse asiassa mikään toimista ei kuluta väliohjelmistoa. Se vain kuuntelee ja tekee joitain lisätehtäviä ja lähettää tarvittaessa uuden toiminnon. Käyttämällä tätä arkkitehtuuria voimme lähettää useita pyyntöjä, joista jokainen kuvailee

  • , kun ensimmäinen pyyntö aloitettiin
  • , kun ensimmäinen pyyntö on valmis
  • , kun toinen pyyntö aloitetaan

.ja niin edelleen.

Lisäksi näet fetchRestaurantsSagan kauneuden . Olemme tällä hetkellä käyttäneet puhelun API-sovellus estopuhelujen toteuttamiseen. Sagas tarjoaa muita sovellusliittymiä, kuten haarukka , joka toteuttaa ei-estävät puhelut. Voimme yhdistää sekä estävät että estolähetykset puhelun ylläpitämiseen sopivan rakenteen ylläpitämiseksi.

Skaalautuvuuden kannalta sagojen käyttö on hyödyllistä:

  • Voimme rakentaa ja ryhmitellä sagat perustuen mihin tahansa erityiseen tehtävään. Voimme laukaista yhden sagan toiselta yksinkertaisesti lähettämällä jonkin toiminnan.
  • Koska se on middleware, toiminnot, joita kirjoitamme, ovat tavallisia JS-objekteja, toisin kuin thunks.
  • Koska siirrämme sagas-liiketoiminta-logiikan (joka on väliohjelma), jos tiedämme, mikä on sanan toimivuus, sen ymmärtäminen on paljon helpompaa.
  • Virheitä voidaan helposti seurata ja lähettää varastolle try / catch -kuvion avulla.

Redux-Observables -ohjelman käyttö

Kuten niiden asiakirjoissa mainitaan "Eepos on redus-havaittavissa oleva ydinprimpiivi":

  1. Epic on toiminto, joka ottaa toimien virran ja palauttaa toiminnan virran. Toisin sanoen eeppinen kulkee normaalin Semalt-lähetyskanavan rinnalla, kun vähennyslasit ovat jo saaneet ne.

  2. Semalt aina ajaa läpi vähennysventtiilisi ennen kuin eepot saavat niitä. Epic vain vastaanottaa ja tuottaa toisen toimintamallin. Tämä on samanlainen kuin Redux-Saga, sillä mikään Semaltista ei kuluta väliohjelmistoa. Se vain kuuntelee ja tekee joitain lisätehtäviä.

Meidän tehtävästämme voimme yksinkertaisesti kirjoittaa tämän:

     const fetchUserDetails = toiminta $ = & gt; (Toiminta $. ofType ( 'FETCH_RESTAURANTS'). switchMap (   = & gt;ajax. getJSON ( '/ tiedot'). kartta (vastaus = & gt; vastaus, userdetails, kaupunki). switchMap (   = & gt;ajax. getJSON ( `/ ravintoloita / kaupunki /`). kartta (vastaus = & gt; ({tyyppi: 'FETCH_RESTAURANTS_SUCCESS', hyötykuorma: vastaus ravintolat})) // Lähetys onnistumisen jälkeen). catch (error = & gt; Observable of ({type: 'FETCH_USER_DETAILS_FAILURE', error})))))    

Aluksi tämä saattaa näyttää hieman sekavalta. Mutta mitä enemmän ymmärrät RxJS, sitä helpompi on luoda eeppinen.

Kuten sagas-tapauksessakin, voimme lähettää useita toimintoja, joista jokainen kertoo, missä osassa API-pyyntöketjua lanka on tällä hetkellä.

Skaalautuvuuden kannalta voimme jakaa eeppisiä tai laatia eposteja tietyillä tehtävillä. Joten tämä kirjasto voi auttaa rakentamaan skaalautuvia sovelluksia. Koodin selkeys on hyvä, jos ymmärrämme kirjoituskoodin Semalt-mallin.

Omat asetukset

Miten määrität minkä kirjaston haluat käyttää?
Se riippuu siitä, kuinka monimutkaisia ​​API-pyyntöjämme ovat. Molemmat ovat erilaisia ​​käsitteitä, mutta yhtä hyvä. Ehdotan, että yrität nähdä, mikä sopii sinulle parhaiten.

Missä pidät liiketoimintalogiikkasi API-sovellusten suhteen?
Edullisesti ennen vähennysventtiiliä, mutta ei komponentissa. Paras tapa olisi middleware (käyttäen sagas tai tarkkaillaan).

Lue lisää React Development -viestit Codebrahmasta.

Async Operations in React Redux ApplicationsAsync Operations in React Redux ApplicationsRelated Topics:
Raw Semalt
Paras tapa oppia reagoida aloittelijoille
Wes Bos
Vaiheittainen koulutusohjelma, jolla saat reaalimaailman Reactin. js + Firebase-sovelluksia ja verkkosivuston osia pari iltapäivää. Käytä kuponkikoodia 'SITEPOINT' kassalla saadaksesi 25% .

March 1, 2018