Asinhronā programmÄ“Å”ana JavaScript (atzvanÄ«Å”ana, solÄ«jums, RxJs)

Sveiki visiem. Sergejs Omeļņickis sazinās. Pirms neilga laika es uzņēmu straumi par reaktÄ«vo programmÄ“Å”anu, kurā es runāju par asinhroniju JavaScript. Å odien es vēlētos veikt piezÄ«mes par Å”o materiālu.

Asinhronā programmÄ“Å”ana JavaScript (atzvanÄ«Å”ana, solÄ«jums, RxJs)

Bet pirms mēs sākam galveno materiālu, mums ir jāizdara ievada piezīme. Tātad, sāksim ar definīcijām: kas ir kaudze un rinda?

Kaudze ir kolekcija, kuras elementi tiek iegūti, pamatojoties uz LIFO principu

Rinda ir kolekcija, kuras elementi iegÅ«ti pēc FIFO principa ā€œpirmais iekŔā, pirmais ārāā€.

Labi, turpināsim.

Asinhronā programmÄ“Å”ana JavaScript (atzvanÄ«Å”ana, solÄ«jums, RxJs)

JavaScript ir viena pavediena programmÄ“Å”anas valoda. Tas nozÄ«mē, ka ir tikai viens izpildes pavediens un viens steks, kurā funkcijas tiek ievietotas izpildes rindā. Tāpēc JavaScript vienlaikus var veikt tikai vienu darbÄ«bu, savukārt citas darbÄ«bas gaidÄ«s savu kārtu stekā, lÄ«dz tās tiks izsauktas.

zvanu kaudze ir datu struktÅ«ra, kas, vienkārÅ”i sakot, ieraksta informāciju par vietu programmā, kur mēs atrodamies. Ja mēs pārejam uz funkciju, mēs virzām tās ievadi uz kaudzes augÅ”daļu. Atgriežoties no funkcijas, mēs izceļam augŔējo elementu no kaudzes un nonākam atpakaļ vietā, kur nosaucām funkciju. Tas ir viss, ko kaudze var darÄ«t. Un tagad ārkārtÄ«gi interesants jautājums. Kā tad asinhronija darbojas JavaScript?

Asinhronā programmÄ“Å”ana JavaScript (atzvanÄ«Å”ana, solÄ«jums, RxJs)

Faktiski, papildus kaudzei, pārlÅ«kprogrammām ir Ä«paÅ”a rinda darbam ar tā saukto WebAPI. Funkcijas Å”ajā rindā tiks izpildÄ«tas kārtÄ«bā tikai pēc tam, kad steka bÅ«s pilnÄ«bā notÄ«rÄ«ta. Tikai pēc tam tie tiek nospiesti no rindas uz steku izpildei. Ja kaudzē Å”obrÄ«d ir vismaz viens elements, tad tos nevar pievienot stekam. TieÅ”i Ŕī iemesla dēļ funkciju izsaukÅ”ana pēc taimauta bieži vien nav precÄ«za laikā, jo funkcija nevar nokļūt no rindas uz steku, kamēr tā ir pilna.

ApskatÄ«sim Å”o piemēru un sāksim ar tā soli pa solim izpildi. PaskatÄ«simies arÄ«, kas notiek sistēmā.

console.log('Hi');
setTimeout(function cb1() {
    console.log('cb1');
}, 5000);
console.log('Bye');

Asinhronā programmÄ“Å”ana JavaScript (atzvanÄ«Å”ana, solÄ«jums, RxJs)

1) Pagaidām nekas nenotiek. Pārlūka konsole ir skaidra, zvanu steka ir tukŔa.

Asinhronā programmÄ“Å”ana JavaScript (atzvanÄ«Å”ana, solÄ«jums, RxJs)

2) Pēc tam komanda console.log('Hi') tiek pievienota zvanu stekam.

Asinhronā programmÄ“Å”ana JavaScript (atzvanÄ«Å”ana, solÄ«jums, RxJs)

3) Un tas ir izpildīts

Asinhronā programmÄ“Å”ana JavaScript (atzvanÄ«Å”ana, solÄ«jums, RxJs)

4) Pēc tam console.log('Hi') tiek noņemts no zvanu steka.

Asinhronā programmÄ“Å”ana JavaScript (atzvanÄ«Å”ana, solÄ«jums, RxJs)

5) Tagad pārejiet uz komandu setTimeout (funkcija cb1() {ā€¦ }). Tas tiek pievienots zvanu stekam.

Asinhronā programmÄ“Å”ana JavaScript (atzvanÄ«Å”ana, solÄ«jums, RxJs)

6) Tiek izpildÄ«ta komanda setTimeout(function cb1() {ā€¦ }). PārlÅ«kprogramma izveido taimeri, kas ir daļa no Web API. Tas veiks atpakaļskaitÄ«Å”anu.

Asinhronā programmÄ“Å”ana JavaScript (atzvanÄ«Å”ana, solÄ«jums, RxJs)

7) komanda setTimeout(function cb1() {... }) ir pabeigusi savu darbu un tiek noņemta no izsaukuma steka.

Asinhronā programmÄ“Å”ana JavaScript (atzvanÄ«Å”ana, solÄ«jums, RxJs)

8) Izsaukuma stekam tiek pievienota komanda console.log('Bye').

Asinhronā programmÄ“Å”ana JavaScript (atzvanÄ«Å”ana, solÄ«jums, RxJs)

9) Tiek izpildīta komanda console.log('Bye').

Asinhronā programmÄ“Å”ana JavaScript (atzvanÄ«Å”ana, solÄ«jums, RxJs)

10) Komanda console.log('Bye') tiek noņemta no zvanu steka.

Asinhronā programmÄ“Å”ana JavaScript (atzvanÄ«Å”ana, solÄ«jums, RxJs)

11) Kad ir pagājuÅ”i vismaz 5000 ms, taimeris pārtrauc darbÄ«bu un ievieto atzvanÄ«Å”anas cb1 atzvanÄ«Å”anas rindā.

Asinhronā programmÄ“Å”ana JavaScript (atzvanÄ«Å”ana, solÄ«jums, RxJs)

12) Notikuma cilpa paņem funkciju cb1 no atzvanÄ«Å”anas rindas un ievieto to zvanu stekā.

Asinhronā programmÄ“Å”ana JavaScript (atzvanÄ«Å”ana, solÄ«jums, RxJs)

13) Funkcija cb1 tiek izpildīta un pievieno console.log('cb1') izsaukuma stekam.

Asinhronā programmÄ“Å”ana JavaScript (atzvanÄ«Å”ana, solÄ«jums, RxJs)

14) Tiek izpildīta komanda console.log('cb1').

Asinhronā programmÄ“Å”ana JavaScript (atzvanÄ«Å”ana, solÄ«jums, RxJs)

15) Komanda console.log('cb1') tiek noņemta no izsaukumu steka.

Asinhronā programmÄ“Å”ana JavaScript (atzvanÄ«Å”ana, solÄ«jums, RxJs)

16) Funkcija cb1 tiek noņemta no zvanu steka.

Apskatīsim piemēru dinamikā:

Asinhronā programmÄ“Å”ana JavaScript (atzvanÄ«Å”ana, solÄ«jums, RxJs)

Mēs apskatījām, kā JavaScript tiek ieviesta asinhronija. Tagad īsi parunāsim par asinhronā koda attīstību.

Asinhronā koda attīstība.

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);
                    })
                })
            })
        })
    })
});

Asinhrono programmÄ“Å”anu, kādu mēs to zinām JavaScript, var ieviest tikai ar funkcijām. Tos tāpat kā jebkuru citu mainÄ«go var nodot citām funkcijām. Tā radās atzvani. Un tas ir forÅ”i, jautri un rotaļīgi, lÄ«dz pārvērÅ”as skumjās, melanholijā un skumjās. Kāpēc? Tas ir vienkārÅ”i:

  • Palielinoties koda sarežģītÄ«bai, projekts ātri pārvērÅ”as neskaidros, atkārtoti ligzdotos blokos - ā€œatzvanÄ«Å”anas elleā€.
  • Kļūdu apstrādi var viegli palaist garām.
  • JÅ«s nevarat atgriezt izteiksmes ar atgrieÅ”anu.

Līdz ar solījuma parādīŔanos situācija kļuva nedaudz labāka.

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);
});

  • ParādÄ«jās solÄ«jumu ķēdes, kas uzlaboja koda lasāmÄ«bu
  • Ir parādÄ«jusies atseviŔķa metode kļūdu uztverÅ”anai
  • Pievienota paralēlas izpildes iespēja, izmantojot Promise.all
  • Mēs varam atrisināt ligzdoto asinhroniju, izmantojot async/await

Taču solījumiem ir savi ierobežojumi. Piemēram, solījumu nevar atcelt, nedejojot ar tamburīnu, un vissvarīgākais ir tas, ka tas darbojas ar vienu vērtību.

Nu, mēs esam gludi pietuvojuÅ”ies reaktÄ«vai programmÄ“Å”anai. Noguris? Par laimi, jÅ«s varat doties uzvārÄ«t tēju, padomāt par to un atgriezties, lai lasÄ«tu vairāk. Un es turpināŔu.

Asinhronā programmÄ“Å”ana JavaScript (atzvanÄ«Å”ana, solÄ«jums, RxJs)

ReaktÄ«vā programmÄ“Å”anaā€Šir programmÄ“Å”anas paradigma, kas vērsta uz datu plÅ«smām un izmaiņu izplatÄ«Å”anu. SÄ«kāk apskatÄ«sim, kas ir datu straume.

// ŠŸŠ¾Š»ŃƒŃ‡Š°ŠµŠ¼ ссыŠ»Šŗу Š½Š° эŠ»ŠµŠ¼ŠµŠ½Ń‚
const input = ducument.querySelector('input');

const eventsArray = [];

// ŠŸŃƒŃˆŠøŠ¼ ŠŗŠ°Š¶Š“Š¾Šµ сŠ¾Š±Ń‹Ń‚ŠøŠµ Š² Š¼Š°ŃŃŠøŠ² eventsArray
input.addEventListener('keyup',
    event => eventsArray.push(event)
);

Iedomāsimies, ka mums ir ievades lauks. Mēs veidojam masÄ«vu, un katram ievades notikuma taustiņam mēs saglabāsim notikumu savā masÄ«vā. Tajā paŔā laikā vēlos atzÄ«mēt, ka mÅ«su masÄ«vs ir sakārtots pēc laika, t.i. vēlāko notikumu indekss ir lielāks nekā agrāko notikumu indekss. Šāds masÄ«vs ir vienkārÅ”ots datu plÅ«smas modelis, taču tas vēl nav plÅ«sma. Lai Å”o masÄ«vu varētu droÅ”i saukt par straumi, tam ir jāspēj kaut kādā veidā informēt abonentus, ka tajā ir ienākuÅ”i jauni dati. Tādējādi mēs nonākam pie plÅ«smas definÄ«cijas.

Datu straume

const { interval } = Rx;
const { take } = RxOperators;

interval(1000).pipe(
    take(4)
)

Asinhronā programmÄ“Å”ana JavaScript (atzvanÄ«Å”ana, solÄ«jums, RxJs)

PlÅ«smaā€Šir datu masÄ«vs, kas sakārtots pēc laika un var norādÄ«t, ka dati ir mainÄ«juÅ”ies. Tagad iedomājieties, cik ērti kļūst rakstÄ«t kodu, kurā vienai darbÄ«bai ir nepiecieÅ”ams izsaukt vairākus notikumus dažādās koda daļās. Mēs vienkārÅ”i abonējam straumi, un tā mums paziņos, kad notiks izmaiņas. Un RxJs bibliotēka to var izdarÄ«t.

Asinhronā programmÄ“Å”ana JavaScript (atzvanÄ«Å”ana, solÄ«jums, RxJs)

RxJS ir bibliotēka darbam ar asinhronām un uz notikumiem balstÄ«tām programmām, izmantojot novērojamas secÄ«bas. Bibliotēka nodroÅ”ina pamata veidu Novērojams, vairāki papildu veidi (Novērotājs, Plānotāji, Subjekti) un operatori darbam ar pasākumiem kā ar kolekcijām (kartēt, filtrēt, samazināt, katru un lÄ«dzÄ«gas no JavaScript masÄ«va).

IzpratÄ«sim Ŕīs bibliotēkas pamatjēdzienus.

Vērojams, novērotājs, producents

Novērojamais ir pirmais pamata veids, ko mēs apskatÄ«sim. Å ajā klasē ir galvenā RxJs ievieÅ”anas daļa. Tas ir saistÄ«ts ar novērojamu straumi, kuru var abonēt, izmantojot abonÄ“Å”anas metodi.

Observable ievieÅ” palÄ«gmehānismu atjauninājumu izveidei, tā saukto Novērotājs. Tiek saukts novērotāja vērtÄ«bu avots Producents. Tas varētu bÅ«t masÄ«vs, iterators, tÄ«mekļa ligzda, kāds notikums utt. Tātad mēs varam teikt, ka novērojamais ir diriÄ£ents starp producentu un novērotāju.

Observable apstrādā trīs veidu Observer notikumus:

  • nākamais ā€“ jauni dati
  • kļūda ā€“ kļūda, ja secÄ«ba beidzās izņēmuma dēļ. Å”is notikums nozÄ«mē arÄ« secÄ«bas pabeigÅ”anu.
  • pabeigts ā€” signāls par secÄ«bas pabeigÅ”anu. Tas nozÄ«mē, ka jaunu datu vairs nebÅ«s.

Apskatīsim demonstrāciju:

Asinhronā programmÄ“Å”ana JavaScript (atzvanÄ«Å”ana, solÄ«jums, RxJs)

Sākumā mēs apstrādāsim vērtības 1, 2, 3 un pēc 1 sekundes. mēs saņemsim 4 un beigsim mūsu straumi.

Skaļi domājot

Un tad es sapratu, ka stāstÄ«t ir interesantāk nekā rakstÄ«t par to. šŸ˜€

AbonēŔana

Kad abonējam straumi, mēs izveidojam jaunu klasi abonementskas dod mums iespēju anulēt abonementu, izmantojot metodi atrakstÄ«ties. Mēs varam arÄ« grupēt abonementus, izmantojot metodi pievienot. Ir loÄ£iski, ka mēs varam atgrupēt pavedienus, izmantojot noņemt. PievienoÅ”anas un noņemÅ”anas metodes kā ievadi pieņem citu abonementu. Es vēlos atzÄ«mēt, ka, anulējot abonementu, mēs anulējam visus bērnu abonementus, it kā viņi bÅ«tu izsaukuÅ”i abonÄ“Å”anas atcelÅ”anas metodi. Uz priekÅ”u.

Straumju veidi

HOT
Auksts

Producents ir izveidots ārpus novērojama
Producents ir izveidots iekŔā novērojams

Dati tiek pārsūtīti brīdī, kad tiek izveidots novērojums
Dati tiek sniegti abonēŔanas brīdī

NepiecieŔama papildu loģika abonēŔanas atcelŔanai
VÄ«tne beidzas pati no sevis

Izmanto attiecības viens pret daudziem
Izmanto attiecības viens pret vienu

Visiem abonementiem ir vienāda nozīme
Abonementi ir neatkarīgi

Dati var tikt zaudēti, ja jums nav abonementa
Atkārtoti izdod visas straumes vērtības jaunam abonementam

Lai sniegtu analoÄ£iju, es domāju par karstu straumi kā filmu teātrÄ«. Kurā brÄ«dÄ« jÅ«s ieradāties, no Ŕī brīža jÅ«s sākāt skatÄ«ties. Es salÄ«dzinātu aukstu plÅ«smu ar zvanu tehnoloÄ£iju jomā. atbalsts. JebkurÅ” zvanÄ«tājs noklausās balss pasta ierakstu no sākuma lÄ«dz beigām, taču jÅ«s varat pārtraukt klausuli, izmantojot anulēt abonementu.

Vēlos atzÄ«mēt, ka ir arÄ« tā saucamās siltās plÅ«smas (ar Å”o definÄ«ciju esmu sastapies ārkārtÄ«gi reti un tikai ārzemju kopienās) - Ŕī ir plÅ«sma, kas no aukstās plÅ«smas pārvērÅ”as karstā. Rodas jautājums - kur izmantot)) Es sniegÅ”u piemēru no prakses.

Es strādāju ar Angular. ViņŔ aktÄ«vi izmanto rxjs. Lai saņemtu datus serverÄ«, es sagaidu aukstu pavedienu un izmantoju Å”o pavedienu veidnē, izmantojot asyncPipe. Ja es izmantoju Å”o cauruli vairākas reizes, tad, atgriežoties pie aukstās straumes definÄ«cijas, katra caurule pieprasÄ«s datus no servera, kas ir maigi izsakoties dÄ«vaini. Un, ja es pārvērÅ”u aukstu straumi siltā, tad pieprasÄ«jums notiks vienu reizi.

Kopumā iesācējiem ir diezgan grūti saprast plūsmu veidu, taču tas ir svarīgi.

Uzņēmējiem

return this.http.get(`${environment.apiUrl}/${this.apiUrl}/trade_companies`)
    .pipe(
        tap(({ data }: TradeCompanyList) => this.companies$$.next(cloneDeep(data))),
        map(({ data }: TradeCompanyList) => data)
    );

Operatori nodroÅ”ina mums iespēju paplaÅ”ināt mÅ«su iespējas strādāt ar straumēm. Tie palÄ«dz kontrolēt notikumus, kas notiek novērojamajā. ApskatÄ«sim pāris populārākos, un sÄ«kāku informāciju par operatoriem var atrast, izmantojot noderÄ«gajā informācijā esoŔās saites.

Operatori - no

Sāksim ar palÄ«goperatoru. Tas izveido novērojamo, pamatojoties uz vienkārÅ”u vērtÄ«bu.

Asinhronā programmÄ“Å”ana JavaScript (atzvanÄ«Å”ana, solÄ«jums, RxJs)

Operatori - filtrs

Asinhronā programmÄ“Å”ana JavaScript (atzvanÄ«Å”ana, solÄ«jums, RxJs)

Filtra operators, kā norāda nosaukums, filtrē straumes signālu. Ja operators atgriež true, tas izlaiž tālāk.

Operatori - ņemiet

Asinhronā programmÄ“Å”ana JavaScript (atzvanÄ«Å”ana, solÄ«jums, RxJs)

take ā€” ņem izstarotāju skaita vērtÄ«bu, pēc kura vÄ«tne beidzas.

Operatori ā€” debounceTime

Asinhronā programmÄ“Å”ana JavaScript (atzvanÄ«Å”ana, solÄ«jums, RxJs)

debounceTime - atmet izstarotās vērtības, kas ietilpst norādītajā laika intervālā starp izvadēm - pēc laika intervāla beigām izstaro pēdējo vērtību.

const { Observable } = Rx;
const { debounceTime, take } = RxOperators;

Observable.create((observer) => {
  let i = 1;
  observer.next(i++);
  // Š˜ŃŠæусŠŗŠ°ŠµŠ¼ Š·Š½Š°Ń‡ŠµŠ½ŠøŠµ рŠ°Š· Š² 1000Š¼Ń
  setInterval(() => {
    observer.next(i++)
  }, 1000);

 // Š˜ŃŠæусŠŗŠ°ŠµŠ¼ Š·Š½Š°Ń‡ŠµŠ½ŠøŠµ рŠ°Š· Š² 1500Š¼Ń
  setInterval(() => {
    observer.next(i++)
  }, 1500);
}).pipe(
  debounceTime(700),  // ŠžŠ¶ŠøŠ“Š°ŠµŠ¼ 700Š¼Ń Š·Š½Š°Ń‡ŠµŠ½Šøя ŠæрŠµŠ¶Š“Šµ чŠµŠ¼ Š¾Š±Ń€Š°Š±Š¾Ń‚Š°Ń‚ŃŒ
  take(3)
);  

Asinhronā programmÄ“Å”ana JavaScript (atzvanÄ«Å”ana, solÄ«jums, RxJs)

Operatori ā€” takeWhile

Asinhronā programmÄ“Å”ana JavaScript (atzvanÄ«Å”ana, solÄ«jums, RxJs)

Izstaro vērtÄ«bas, lÄ«dz takeWhile atgriež false, pēc tam tiek atcelta pavediena abonÄ“Å”ana.

const { Observable } = Rx;
const { debounceTime, takeWhile } = RxOperators;

Observable.create((observer) => {
  let i = 1;
  observer.next(i++);
  // Š˜ŃŠæусŠŗŠ°ŠµŠ¼ Š·Š½Š°Ń‡ŠµŠ½ŠøŠµ рŠ°Š· Š² 1000Š¼Ń
  setInterval(() => {
    observer.next(i++)
  }, 1000);
}).pipe(
  takeWhile( producer =>  producer < 5 )
);  

Asinhronā programmÄ“Å”ana JavaScript (atzvanÄ«Å”ana, solÄ«jums, RxJs)

Operatori - apvienotJaunākais

CombinLatest operators ir nedaudz līdzīgs solīdam.all. Tas apvieno vairākus pavedienus vienā. Pēc tam, kad katrs pavediens veic vismaz vienu emisiju, mēs iegūstam jaunākās vērtības no katra masīva veidā. Turklāt pēc jebkādas emisijas no apvienotajām plūsmām tas dos jaunas vērtības.

Asinhronā programmÄ“Å”ana JavaScript (atzvanÄ«Å”ana, solÄ«jums, RxJs)

const { combineLatest, Observable } = Rx;
const { take } = RxOperators;

const observer_1 = Observable.create((observer) => {
  let i = 1;
  // Š˜ŃŠæусŠŗŠ°ŠµŠ¼ Š·Š½Š°Ń‡ŠµŠ½ŠøŠµ рŠ°Š· Š² 1000Š¼Ń
  setInterval(() => {
    observer.next('a: ' + i++);
  }, 1000);
});

const observer_2 = Observable.create((observer) => {
  let i = 1;
  // Š˜ŃŠæусŠŗŠ°ŠµŠ¼ Š·Š½Š°Ń‡ŠµŠ½ŠøŠµ рŠ°Š· Š² 750Š¼Ń
  setInterval(() => {
    observer.next('b: ' + i++);
  }, 750);
});

combineLatest(observer_1, observer_2).pipe(take(5));

Asinhronā programmÄ“Å”ana JavaScript (atzvanÄ«Å”ana, solÄ«jums, RxJs)

Operatori - zip

Zip ā€” gaida vērtÄ«bu no katra pavediena un veido masÄ«vu, pamatojoties uz Ŕīm vērtÄ«bām. Ja vērtÄ«ba nenāk no neviena pavediena, grupa netiks izveidota.

Asinhronā programmÄ“Å”ana JavaScript (atzvanÄ«Å”ana, solÄ«jums, RxJs)

const { zip, Observable } = Rx;
const { take } = RxOperators;

const observer_1 = Observable.create((observer) => {
  let i = 1;
  // Š˜ŃŠæусŠŗŠ°ŠµŠ¼ Š·Š½Š°Ń‡ŠµŠ½ŠøŠµ рŠ°Š· Š² 1000Š¼Ń
  setInterval(() => {
    observer.next('a: ' + i++);
  }, 1000);
});

const observer_2 = Observable.create((observer) => {
  let i = 1;
  // Š˜ŃŠæусŠŗŠ°ŠµŠ¼ Š·Š½Š°Ń‡ŠµŠ½ŠøŠµ рŠ°Š· Š² 750
  setInterval(() => {
    observer.next('b: ' + i++);
  }, 750);
});

const observer_3 = Observable.create((observer) => {
  let i = 1;
  // Š˜ŃŠæусŠŗŠ°ŠµŠ¼ Š·Š½Š°Ń‡ŠµŠ½ŠøŠµ рŠ°Š· Š² 500
  setInterval(() => {
    observer.next('c: ' + i++);
  }, 500);
});

zip(observer_1, observer_2, observer_3).pipe(take(5));

Asinhronā programmÄ“Å”ana JavaScript (atzvanÄ«Å”ana, solÄ«jums, RxJs)

Operatori - forkJoin

forkJoin arī savieno pavedienus, taču tas izstaro vērtību tikai tad, kad visi pavedieni ir pabeigti.

Asinhronā programmÄ“Å”ana JavaScript (atzvanÄ«Å”ana, solÄ«jums, RxJs)

const { forkJoin, Observable } = Rx;
const { take } = RxOperators;

const observer_1 = Observable.create((observer) => {
  let i = 1;
  // Š˜ŃŠæусŠŗŠ°ŠµŠ¼ Š·Š½Š°Ń‡ŠµŠ½ŠøŠµ рŠ°Š· Š² 1000Š¼Ń
  setInterval(() => {
    observer.next('a: ' + i++);
  }, 1000);
}).pipe(take(3));

const observer_2 = Observable.create((observer) => {
  let i = 1;
  // Š˜ŃŠæусŠŗŠ°ŠµŠ¼ Š·Š½Š°Ń‡ŠµŠ½ŠøŠµ рŠ°Š· Š² 750
  setInterval(() => {
    observer.next('b: ' + i++);
  }, 750);
}).pipe(take(5));

const observer_3 = Observable.create((observer) => {
  let i = 1;
  // Š˜ŃŠæусŠŗŠ°ŠµŠ¼ Š·Š½Š°Ń‡ŠµŠ½ŠøŠµ рŠ°Š· Š² 500
  setInterval(() => {
    observer.next('c: ' + i++);
  }, 500);
}).pipe(take(4));

forkJoin(observer_1, observer_2, observer_3);

Asinhronā programmÄ“Å”ana JavaScript (atzvanÄ«Å”ana, solÄ«jums, RxJs)

Operatori - karte

Kartes transformācijas operators pārveido emitētāja vērtību jaunā.

Asinhronā programmÄ“Å”ana JavaScript (atzvanÄ«Å”ana, solÄ«jums, RxJs)

const {  Observable } = Rx;
const { take, map } = RxOperators;

Observable.create((observer) => {
  let i = 1;
  // Š˜ŃŠæусŠŗŠ°ŠµŠ¼ Š·Š½Š°Ń‡ŠµŠ½ŠøŠµ рŠ°Š· Š² 1000Š¼Ń
  setInterval(() => {
    observer.next(i++);
  }, 1000);
}).pipe(
  map(x => x * 10),
  take(3)
);

Asinhronā programmÄ“Å”ana JavaScript (atzvanÄ«Å”ana, solÄ«jums, RxJs)

Operatori ā€“ kopÄ«gojiet, pieskarieties

PieskarÅ”anās operators ļauj veikt blakusparādÄ«bas, tas ir, jebkuras darbÄ«bas, kas neietekmē secÄ«bu.

DalÄ«Å”anas utilÄ«ta operators var pārvērst aukstu straumi karstā.

Asinhronā programmÄ“Å”ana JavaScript (atzvanÄ«Å”ana, solÄ«jums, RxJs)

Esam pabeiguÅ”i darbu ar operatoriem. Pārejam pie tēmas.

Skaļi domājot

Un tad es devos iedzert tēju. Man ir apnikuÅ”i Å”ie piemēri šŸ˜€

PriekŔmeta ģimene

PriekÅ”meta saime ir lielisks karsto plÅ«smu piemērs. Å Ä«s klases ir sava veida hibrÄ«ds, kas vienlaikus darbojas kā novērojams un novērotājs. Tā kā tēma ir aktuāla, ir jāatsakās no tā abonÄ“Å”anas. Ja mēs runājam par galvenajām metodēm, tad tās ir:

  • nākamais ā€“ jaunu datu pārsÅ«tÄ«Å”ana uz straumi
  • kļūda ā€“ kļūda un pavediena pārtraukÅ”ana
  • pabeigt ā€“ pavediena pabeigÅ”ana
  • abonēt ā€” abonēt straumi
  • atteikties no straumes abonÄ“Å”anas
  • asObservable ā€“ pārveidoties par novērotāju
  • toPromise ā€“ pārvērÅ”as par solÄ«jumu

Ir 4 5 priekŔmetu veidi.

Skaļi domājot

Straumē runāja 4 cilvēki, bet izrādījās, ka viņi pievienoja vēl vienu. Kā saka, dzīvo un mācies.

VienkārÅ”s priekÅ”mets new Subject()ā€“ vienkārŔākais priekÅ”metu veids. Izveidots bez parametriem. PārsÅ«ta vērtÄ«bas, kas saņemtas tikai pēc abonÄ“Å”anas.

BehaviorSubject new BehaviorSubject( defaultData<T> ) ā€“ manuprāt, visizplatÄ«tākais priekÅ”meta veids. Ievade iegÅ«st noklusējuma vērtÄ«bu. Vienmēr saglabā pēdējā numura datus, kas tiek pārsÅ«tÄ«ti abonÄ“Å”anas laikā. Å ai klasei ir arÄ« noderÄ«ga vērtÄ«bu metode, kas atgriež straumes paÅ”reizējo vērtÄ«bu.

Replay Subject new ReplaySubject(bufferSize?: number, windowTime?: number) ā€” Ievade pēc izvēles var izmantot kā pirmo argumentu vērtÄ«bu bufera lielumu, ko tā saglabās sevÄ«, un kā otro argumentu, kurā mums ir nepiecieÅ”amas izmaiņas.

AsyncSubject new AsyncSubject() ā€” abonÄ“Å”anas laikā nekas nenotiek, un vērtÄ«ba tiks atgriezta tikai tad, kad tā bÅ«s pabeigta. Tiks atgriezta tikai pēdējā straumes vērtÄ«ba.

WebSocketSubject new WebSocketSubject(urlConfigOrSource: string | WebSocketSubjectConfig<T> | Observable<T>, destination?: Observer<T>) ā€” Dokumentācija par viņu klusē, un es viņu redzu pirmo reizi. Ja kāds zina ar ko viņŔ nodarbojas, lÅ«dzu rakstiet un mēs pievienosim.

FÅ«. Mēs esam apskatÄ«juÅ”i visu, ko es Å”odien gribēju jums pastāstÄ«t. Ceru, ka Ŕī informācija bija noderÄ«ga. Atsauču sarakstu varat izlasÄ«t pats noderÄ«gas informācijas cilnē.

noderīga informācija

Avots: www.habr.com

Pievieno komentāru