Kaixo guztioi. Sergey Omelnitsky harremanetan dago. Duela ez asko programazio erreaktiboari buruzko korronte bat antolatu nuen, non JavaScript-en asinkroniari buruz hitz egin nuen. Gaur material honi buruzko oharrak hartu nahi nituzke.
Baina material nagusiari ekin aurretik, sarrerako ohar bat egin behar dugu. Beraz, has gaitezen definizioekin: zer da pila eta ilara bat?
Pila bilduma bat da, zeinen elementuak LIFO azken sartu eta lehen ateratzen den oinarrian lortzen diren
piztu Bilduma bat da, zeinaren elementuak FIFOren arabera lortzen diren lehen-sarrerako, lehen-irteteko oinarrian
Ados, jarrai dezagun.
JavaScript hari bakarreko programazio-lengoaia da. Horrek esan nahi du exekuzio hari bakarra dagoela eta pila bat, zeinetan funtzioak exekutatzeko ilaran jartzen diren. Hori dela eta, JavaScript-ek eragiketa bakarra egin dezake aldi berean, eta beste eragiketa batzuek pilaren txanda itxarongo dute deitzen zaien arte.
Dei pila datu-egitura bat da, besterik gabe, gauden programako tokiari buruzko informazioa erregistratzen duena. Funtzio batera pasatzen bagara, bere sarrera pilaren goiko aldera bultzatzen dugu. Funtzio batetik itzultzen garenean, pilatik goiko elementua ateratzen dugu eta funtzioari deitzen diogun tokira itzuliko gara. Hau da pilak egin dezakeen guztia. Eta orain galdera oso interesgarria. Nola funtzionatzen du asinkroniak JavasScript-en?
Izan ere, pilaz gain, nabigatzaileek WebAPI deritzonarekin lan egiteko ilara berezi bat dute. Ilara honetako funtzioak ordenan exekutatuko dira pila guztiz garbitu ondoren. Horren ondoren bakarrik ilaratik pilara bultzatzen dira exekutatzeko. Une honetan pila batean gutxienez elementu bat badago, ezin dira pilara gehitu. Hain zuzen, horregatik denbora-mugaz funtzioak deitzea ez da sarri denboran zehatza, funtzioa ezin baita ilaratik pilara iritsi beteta dagoen bitartean.
Ikus dezagun hurrengo adibidea eta hasi urratsez urrats exekutatzen. Ikus dezagun sisteman zer gertatzen den ere.
1) Oraindik ez da ezer gertatzen. Arakatzailearen kontsola garbi dago, deien pila hutsik dago.
2) Ondoren console.log('Hi') komandoa gehitzen da deien pilara.
3) Eta betetzen da
4) Ondoren console.log('Hi') dei-pilatik kenduko da.
5) Orain joan setTimeout komandora (funtzioa cb1() {β¦ }). Deien pilara gehitzen da.
6) setTimeout(function cb1() {β¦ }) komandoa exekutatzen da. Arakatzaileak Web APIaren parte den tenporizadore bat sortzen du. Atzerako kontaketa egingo du.
7) setTimeout(function cb1() {... }) komandoak bere lana amaitu du eta deien pilatik kendu da.
8) console.log('Bye') komandoa gehitzen da deien pilara.
9) console.log('Bye') komandoa exekutatzen da.
10) Komando console.log('Bye') deien pilatik kendu da.
11) Gutxienez 5000 ms igaro ondoren, tenporizadorea amaitzen da eta cb1 dei-itzulera ipintzen du dei-itzuleraren ilaran.
12) Gertaeren begiztak cb1 funtzioa dei-itzulera ilaratik hartzen du eta dei-pilean jartzen du.
13) cb1 funtzioa exekutatzen da eta console.log('cb1') gehitzen du deien pilara.
14) console.log('cb1') komandoa exekutatzen da.
15) Komando console.log('cb1') deien pilatik kendu da.
16) cb1 funtzioa deien pilatik kentzen da.
Ikus dezagun dinamikako adibide bat:
Beno, JavaScript-en asinkronia nola inplementatzen den aztertu dugu. Orain hitz egin dezagun laburki kode asinkronoaren bilakaerari buruz.
Kode asinkronoaren bilakaera.
a(function (resultsFromA) {
b(resultsFromA, function (resultsFromB) {
c(resultsFromB, function (resultsFromC) {
d(resultsFromC, function (resultsFromD) {
e(resultsFromD, function (resultsFromE) {
f(resultsFromE, function (resultsFromF) {
console.log(resultsFromF);
})
})
})
})
})
});
JavaScript-en ezagutzen dugun programazio asinkronoa funtzioen bidez soilik inplementa daiteke. Beste edozein aldagai bezala beste funtzio batzuetara pasa daitezke. Horrela sortu ziren callback-ak. Eta polita, dibertigarria eta jostagarria da, tristura, malenkonia eta tristura bihurtu arte. Zergatik? Sinplea da:
Kodearen konplexutasuna handitzen den heinean, proiektua behin eta berriz habiaraturiko bloke ilun bihurtzen da - "callback hell".
Erroreen kudeaketa erraza izan daiteke galtzea.
Ezin dituzu itzuli adierazpenak itzuli.
Promiseren etorrerarekin, egoera apur bat hobetu zen.
new Promise(function(resolve, reject) {
setTimeout(() => resolve(1), 2000);
}).then((result) => {
alert(result);
return result + 2;
}).then((result) => {
throw new Error('FAILED HERE');
alert(result);
return result + 2;
}).then((result) => {
alert(result);
return result + 2;
}).catch((e) => {
console.log('error: ', e);
});
Promes-kateak agertu ziren, eta horrek kodearen irakurgarritasuna hobetu zuen
Akatsak harrapatzeko metodo bereizi bat agertu da
Promise.all erabiliz paralelo exekutatzeko aukera gehitu da
Async/wait erabiliz habiatutako asinkronia ebatzi dezakegu
Baina promesek bere mugak dituzte. Esaterako, promesa bat ezin da bertan behera utzi panderoarekin dantza egin gabe, eta garrantzitsuena balio batekin funtzionatzea da.
Beno, leunki hurbildu gara programazio erreaktibora. Nekatuta? Tira, zorionez, tea prestatzera joan zaitezke, pentsatu eta gehiago irakurtzera bueltatu zaitezke. Eta jarraituko dut.
Programazio erreaktiboaβdatu-fluxuetan eta aldaketaren hedapenean ardaztutako programazio paradigma da. Ikus dezagun zer den datu korronte bat.
Imajina dezagun sarrera eremu bat dugula. Array bat sortzen ari gara eta sarrerako gertaeraren tekla bakoitzeko gertaera gure matrizean gordeko dugu. Aldi berean, gure array denboraren arabera ordenatuta dagoela adierazi nahiko nuke, hau da. geroagoko gertaeren indizea lehenagokoen indizea baino handiagoa da. Halako array bat datu-fluxu baten eredu sinplifikatu bat da, baina oraindik ez da fluxu bat. Array honi korronte deitzeko modu seguruan, harpidedunei datu berriak iritsi direla jakinarazteko gai izan behar du nolabait. Horrela, fluxuaren definiziora iritsiko gara.
Fluxuaβdenboraren arabera ordenatutako datu-matrize bat da, datuak aldatu direla adieraz dezakeena. Orain imajinatu zein komenigarria den kodea idaztea, ekintza batek hainbat gertaera deitzea eskatzen duen kodearen zati ezberdinetan. Korrontean harpidetzen gara eta aldaketak gertatzen direnean jakinaraziko digu. Eta RxJs liburutegiak hau egin dezake.
RxJS sekuentzia behagarriak erabiliz programa asinkronoekin eta gertaeretan oinarritutakoekin lan egiteko liburutegia da. Liburutegiak oinarrizko mota bat eskaintzen du beha, hainbat mota laguntzaile (Behatzailea, Programatzaileak, Gaiak) eta ekitaldiekin lan egiteko operadoreak bildumekin bezala (mapatu, iragazi, murriztu, bakoitza eta JavaScript Array-ko antzekoak).
Uler ditzagun liburutegi honen oinarrizko kontzeptuak.
Behagarria, Behatzailea, Ekoizlea
Behagarria da aztertuko dugun lehen oinarrizko mota. Klase honek RxJs inplementazioaren zati nagusia dauka. Korronte behagarri batekin lotuta dago, harpidetza metodoa erabiliz harpidetu daitekeena.
Observablek eguneraketak sortzeko laguntza-mekanismo bat ezartzen du, deitzen dena Behatzaile. Behatzaileentzako balioen iturria deitzen da Produktorea. Hau array bat, iteratzailea, web socketa, gertaera motaren bat eta abar izan daiteke. Beraz, behagarria Producer eta Observer arteko eroalea dela esan dezakegu.
Observable-k Observer-eko hiru gertaera mota kudeatzen ditu:
hurrengoa - datu berriak
error - errore bat sekuentzia salbuespen baten ondorioz amaitu bada. gertaera honek sekuentzia osatzea ere suposatzen du.
complete β sekuentziaren amaierari buruzko seinale. Horrek esan nahi du ez dela datu berri gehiago egongo.
Ikus dezagun demoa:
Hasieran 1, 2, 3 eta segundo 1 ondoren prozesatu egingo ditugu. 4 lortuko dugu eta gure korrontea amaituko dugu.
Ozen pentsatzen
Eta orduan konturatu nintzen kontatzea interesgarriagoa zela idaztea baino. π
Harpidetza
Korronte batera harpidetzen garenean klase berri bat sortzen dugu harpidetzahorrek metodoa erabiliz harpidetza kentzeko aukera ematen digu harpidetza kendu. Harpidetzak ere taldeka ditzakegu metodoa erabiliz gehitu. Beno, logikoa da hariak erabiliz destaldekatu ditzakegula kendu. Gehitu eta kendu metodoek beste harpidetza bat onartzen dute sarrera gisa. Kontuan izan nahi dut harpidetza kentzen dugunean, haur-harpidetza guztiak kentzen ditugula harpidetza kentzeko metodoa deitu balute bezala. Segi aurrera.
Korronte motak
HOT
HOTZA
Ekoizlea behagarritik kanpo sortzen da
Ekoizlea behagarriaren barruan sortzen da
Datuak behagarria sortzen den unean transferitzen dira
Datuak harpidetza egiteko unean ematen dira
Logika gehigarria behar da harpidetza kentzeko
Haria bere kabuz amaitzen da
Batetik askorako harremana erabiltzen du
Bat-bateko harremana erabiltzen du
Harpidetza guztiek esanahi bera dute
Harpidetzak independenteak dira
Datuak gal daitezke harpidetzarik ez baduzu
Korronteen balio guztiak berriro argitaratzen ditu harpidetza berri baterako
Analogia bat emateko, korronte bero bat antzoki bateko pelikula gisa pentsatuko nuke. Zein momentutan iritsi zinen, momentu horretatik hasi zinen ikusten. Fluxu hotz bat teknologiako dei batekin alderatuko nuke. euskarria. Deitzen duen edozeinek ahots-mezuaren grabazioa entzuten du hasieratik amaierara, baina harpidetza kentzea erabiliz eseki dezakezu.
Kontuan izan nahiko nuke fluxu epelak deitzen direnak ere badirela (oso gutxitan topatu dut definizio hau eta atzerriko komunitateetan bakarrik) - fluxu hotzetik bero izatera pasatzen den fluxua da. Galdera sortzen da - non erabili)) Praktikaren adibide bat emango dut.
Angularrekin ari naiz lanean. Aktiboki erabiltzen ditu rxjs. Zerbitzariari datuak jasotzeko, hari hotz bat espero dut eta hari hau erabili txantiloian asyncPipe erabiliz. Hodi hau hainbat aldiz erabiltzen badut, orduan, hotz-korrontearen definiziora itzuliz, hodi bakoitzak zerbitzariari datuak eskatuko dizkio, eta hori bitxia da. Eta korronte hotz bat epel bihurtzen badut, eskaera behin gertatuko da.
Oro har, fluxu mota ulertzea nahiko zaila da hasiberrientzat, baina garrantzitsua.
Operadore
return this.http.get(`${environment.apiUrl}/${this.apiUrl}/trade_companies`)
.pipe(
tap(({ data }: TradeCompanyList) => this.companies$$.next(cloneDeep(data))),
map(({ data }: TradeCompanyList) => data)
);
Operadoreek korronteekin lan egiteko gaitasuna zabaltzeko gaitasuna eskaintzen digute. Behagarrian gertatzen diren gertaerak kontrolatzen laguntzen dute. Ezagunenak diren pare bat aztertuko ditugu, eta operadoreei buruzko xehetasun gehiago aurki daitezke informazio erabilgarriako estekak erabiliz.
Eragileak - de
Has gaitezen of operadore laguntzailearekin. Balio sinple batean oinarritutako Behagarri bat sortzen du.
Eragileak - iragazkia
Iragazki-operadoreak, izenak dioen bezala, korrontearen seinalea iragazten du. Eragileak egia itzultzen badu, gehiago saltatzen du.
Eragileak - hartu
hartu β Igorle-kopuruaren balioa hartzen du, eta ondoren haria amaitzen da.
Eragileak - debounceTime
debounceTime - irteeraren arteko zehaztutako denbora tartean sartzen diren igorritako balioak baztertzen ditu - denbora tartea igaro ondoren, azken balioa igortzen du.
combineLatest operadorea promise.all-en antzekoa da. Hainbat hari konbinatzen ditu bakarrean. Hari bakoitzak gutxienez igorpen bat egin ondoren, bakoitzaren azken balioak jasoko ditugu array moduan. Gainera, bateratutako korronteetatik edozein igorpenaren ondoren, balio berriak emango ditu.
Zip - Hari bakoitzeko balio baten zain dago eta balio hauetan oinarritutako array bat osatzen du. Balioa inongo haritik ez badator, orduan ez da taldea osatuko.
Ukitu-operadoreak bigarren mailako efektuak egiteko aukera ematen du, hau da, sekuentziari eragiten ez dioten ekintza guztiak.
Partekatze-zerbitzuaren operadoreak korronte hotz bat bero bihur dezake.
Operadoreekin amaitu dugu. Goazen gaira.
Ozen pentsatzen
Eta gero tea edatera joan nintzen. Nekatuta nago adibide hauekin π
Gaia familia
Subjektu familia fluxu beroen adibide nagusia da. Klase hauek aldi berean behagarri eta behatzaile gisa jokatzen duten hibrido mota bat dira. Gaia hari beroa denez, beharrezkoa da harpidetza kentzea. Metodo nagusiei buruz hitz egiten badugu, hauek dira:
hurrengoa - datu berriak korrontera transferitzea
errorea - errorea eta hariaren amaiera
osatu β haria osatzea
harpidetu β korronte batera harpidetu
unsubscribe β kendu harpidetza korrontetik
asObservable β behatzaile bihurtu
toPromise - promesa bihurtzen da
4 5 irakasgai mota daude.
Ozen pentsatzen
4 pertsona zeuden korrontean hizketan, baina beste bat gehitu zuten. Esaten den bezala, bizi eta ikasi.
Gai sinplea new Subject()β irakasgai mota errazena. Parametrorik gabe sortua. Harpidetza ondoren bakarrik jasotako balioak transmititzen ditu.
PortaeraGaia new BehaviorSubject( defaultData<T> ) β nire ustez, gai mota ohikoena. Sarrerak balio lehenetsia hartzen du. Azken alearen datuak gordetzen ditu beti, harpidetza egiterakoan transmititzen direnak. Klase honek balio-metodo erabilgarria ere badu, korrontearen uneko balioa itzultzen duena.
Erreproduzitu gaia new ReplaySubject(bufferSize?: number, windowTime?: number) β Sarrerak aukeran har dezake lehen argumentu gisa bere baitan gordeko duen balio-buffer-aren tamaina, eta bigarren gisa aldaketak behar ditugun denbora.
AsyncSubject new AsyncSubject() β ez da ezer gertatzen harpidetzean, eta balioa amaitutakoan bakarrik itzuliko da. Korrontearen azken balioa bakarrik itzuliko da.
WebSocketSubject new WebSocketSubject(urlConfigOrSource: string | WebSocketSubjectConfig<T> | Observable<T>, destination?: Observer<T>) β Dokumentazioa isilik dago berari buruz eta lehen aldiz ikusten ari naiz. Norbaitek badaki zer egiten duen, mesedez idatzi eta gehituko dugu.
Uf. Beno, gaur kontatu nahi dizudan guztia azaldu dugu. Informazio hau erabilgarria izatea espero dut. Erreferentzien zerrenda zuk zeuk irakur dezakezu informazio erabilgarria fitxan.