Asynchronous nga programming sa JavaScript (Callback, Promise, RxJs)
Kumusta tanan. Sa paghikap Omelnitsky Sergey. Dili pa lang dugay, nag-host ko og stream sa reactive programming, diin naghisgot ko bahin sa asynchrony sa JavaScript. Karon gusto nakong i-summarize kini nga materyal.
Apan sa dili pa nato sugdan ang pangunang materyal, kinahanglang maghimo kitag pasiuna. Mao nga magsugod kita sa mga kahulugan: unsa ang stack ug pila?
Stack mao ang usa ka koleksyon kansang mga elemento gikuha sa usa ka "last in, first out" LIFO nga basehan
Pag-pila usa ka koleksyon kansang mga elemento nakuha sumala sa prinsipyo ("first in, first out" FIFO
Okay, magpadayon ta.
Ang JavaScript usa ka single-threaded programming language. Kini nagpasabot nga kini adunay usa lamang ka hilo sa pagpatuman ug usa ka stack diin ang mga gimbuhaton gipila alang sa pagpatuman. Busa, ang JavaScript makahimo lamang sa usa ka operasyon sa usa ka higayon, samtang ang ubang mga operasyon maghulat sa ilang turn sa stack hangtud nga sila matawag.
Tawag nga stack usa ka istruktura sa datos nga, sa yano nga mga termino, nagrekord sa kasayuran bahin sa lugar sa programa kung asa kita. Kung molukso kita sa usa ka function, atong iduso ang pagsulod niini sa ibabaw sa stack. Kung kita mobalik gikan sa usa ka function, atong i-pop ang pinakataas nga elemento gikan sa stack ug matapos kung diin kita nagtawag niini nga function. Mao ra kana ang mahimo sa stack. Ug karon usa ka makapaikag kaayo nga pangutana. Giunsa man ang asynchrony sa JavasScript?
Sa tinuud, dugang sa stack, ang mga browser adunay espesyal nga pila alang sa pagtrabaho sa gitawag nga WebAPI. Ang mga gimbuhaton gikan niini nga pila ipatuman sa han-ay lamang human ang stack hingpit nga mahawan. Human lamang nga sila gibutang gikan sa pila ngadto sa stack alang sa pagpatay. Kung adunay labing menos usa ka elemento sa stack sa pagkakaron, nan dili sila makuha sa stack. Tungod lang niini, ang pagtawag sa mga function pinaagi sa timeout kanunay nga dili tukma sa oras, tungod kay ang function dili makuha gikan sa pila hangtod sa stack samtang kini puno.
Atong tan-awon ang mosunod nga pananglitan ug atong susihon kini sa sunod-sunod nga lakang. Atong tan-awon usab kung unsa ang mahitabo sa sistema.
1) Sa pagkakaron walay nahitabo. Ang browser console limpyo, ang call stack walay sulod.
2) Dayon ang command console.log('Hi') idugang sa call stack.
3) Ug kini natuman
4) Unya console.log('Hi') gikuha gikan sa tawag stack.
5) Karon magpadayon kita sa setTimeout(function cb1() {β¦ }) command. Gidugang kini sa call stack.
6) Ang setTimeout(function cb1() {... }) nga sugo kay gipatuman. Ang browser nagmugna og timer nga kabahin sa Web API. Maghimo kini og countdown.
7) Ang setTimeout(function cb1() {... }) nga sugo nakompleto na ang trabaho niini ug gikuha gikan sa call stack.
8) Ang console.log('Bye') nga sugo gidugang sa call stack.
9) Ang console.log('Bye') nga sugo gipatuman.
10) Ang command console.log('Bye') gikuha gikan sa call stack.
11) Human sa labing menos 5000ms ang milabay, ang timer matapos ug gibutang ang cb1 callback ngadto sa callback queue.
12) Ang event loop nagkuha sa function cb1 gikan sa callback queue ug giduso kini ngadto sa call stack.
13) Ang cb1 function gipatuman ug nagdugang console.log('cb1') sa call stack.
14) Ang console.log('cb1') nga sugo gipatuman.
15) Ang command console.log('cb1') gikuha gikan sa call stack.
16) Ang function cb1 gikuha gikan sa call stack.
Atong tan-awon ang usa ka pananglitan sa dynamics:
Aw, among gitan-aw kung giunsa gipatuman ang asynchrony sa JavaScript. Karon hisgotan ta sa daklit bahin sa ebolusyon sa asynchronous code.
Ang ebolusyon sa asynchronous code.
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);
})
})
})
})
})
});
Ang asynchronous nga programming sama sa nahibal-an namon sa JavaScript mahimo ra sa mga gimbuhaton. Mahimo silang ipasa sama sa bisan unsang lain nga variable sa ubang mga gimbuhaton. Ingon niini ang pagkahimugso sa mga callback. Ug kini bugnaw, makalingaw ug mainiton, hangtud nga kini nahimong kasubo, kasubo ug kasubo. Ngano man? Oo, kini yano:
Samtang nagkadako ang pagkakomplikado sa code, ang proyekto dali nga nahimo nga dili klaro nga daghang mga salag nga mga bloke - "callback hell".
Ang pagdumala sa sayop daling mataligam-an.
Dili ka makabalik sa mga ekspresyon nga adunay pagbalik.
Sa pag-abot sa Saad, ang sitwasyon nahimong mas maayo.
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);
});
Nagpakita ang mga kadena sa saad, nga nagpauswag sa pagkabasa sa code
Adunay usa ka bulag nga paagi sa interception sa mga sayup
Parallel execution uban sa Promise.all gidugang
Masulbad namo ang nested asynchrony gamit ang async/wait
Apan ang saad adunay mga limitasyon. Pananglitan, ang usa ka saad, nga walay pagsayaw gamit ang tamburin, dili mahimong kanselahon, ug labaw sa tanan, kini molihok sa usa ka bili.
Aw, ania kami hapsay nga nagkaduol sa reaktibo nga programa. Gikapoy? Aw, ang maayo nga butang mao, mahimo ka nga mag-brew sa pipila ka mga kanaway, mag-brainstorm ug mobalik aron magbasa pa. Ug ako magpadayon.
Reaktibo nga programmingβ- usa ka paradigma sa pagprograma nga nakapunting sa mga pag-agos sa datos ug ang pagpadaghan sa mga pagbag-o. Atong tan-awon pag-ayo kung unsa ang usa ka stream sa datos.
Hunahunaa nga kita adunay usa ka input field. Naghimo kami og array, ug alang sa matag keyup sa input event, among tipigan ang panghitabo sa among array. Sa parehas nga oras, gusto nako nga timan-an nga ang among array gisunud sa oras, i.e. ang indeks sa ulahing mga panghitabo mas dako kay sa indeks sa mga nauna. Ang ingon nga array usa ka gipasimple nga data flow model, apan dili pa kini usa ka dagan. Aron kini nga array luwas nga matawag nga usa ka sapa, kini kinahanglan nga makapahibalo sa mga subscriber nga ang bag-ong datos miabut niini. Sa ingon moabut kita sa kahulugan sa dagan.
Ang pag-agosβusa ka han-ay sa mga datos nga gisunod sa oras nga mahimong magpakita nga ang datos nausab. Karon hunahunaa kung unsa ka dali ang pagsulat sa code diin kinahanglan nimo nga ma-trigger ang daghang mga panghitabo sa lainlaing mga bahin sa code alang sa usa ka aksyon. Nag-subscribe lang kami sa sapa ug kini magsulti kanamo kung adunay mga pagbag-o. Ug ang RxJs library makahimo niini.
RxJS mao ang usa ka librarya alang sa pagtrabaho uban sa asynchronous ug event-based nga mga programa gamit ang makita nga mga han-ay. Ang librarya naghatag sa panguna nga tipo Mamatikdan, pipila ka matang sa katabang (Mga tigpaniid, scheduler, mga subject) ug mga operator alang sa pagtrabaho sa mga panghitabo sama sa mga koleksyon (mapa, filter, pagpakunhod, matag ug susama gikan sa JavaScript Array).
Atong sabton ang sukaranang mga konsepto niini nga librarya.
Mapaniid, Mapaniid, Magbubuhat
Ang obserbahan mao ang una nga base nga tipo nga atong tan-awon. Kini nga klase naglangkob sa panguna nga bahin sa pagpatuman sa RxJs. Nalambigit kini sa usa ka makita nga sapa, nga mahimong ma-subscribe gamit ang pamaagi sa pag-subscribe.
Ang Observable nagpatuman sa usa ka auxiliary nga mekanismo alang sa paghimo og mga update, ang gitawag nga observer. Ang gigikanan sa mga kantidad alang sa usa ka Observer gitawag producer. Kini mahimo nga usa ka array, usa ka iterator, usa ka web socket, usa ka matang sa panghitabo, ug uban pa. Busa makaingon kita nga ang observable usa ka conductor tali sa Producer ug Observer.
Ang Observable nagdumala sa tulo ka matang sa Observer nga mga panghitabo:
sunod - bag-ong datos
sayup - usa ka sayup kung ang pagkasunod-sunod natapos tungod sa usa ka eksepsiyon. kini nga panghitabo nagpasabot usab sa katapusan sa han-ay.
kompleto - usa ka signal bahin sa katapusan sa han-ay. Kini nagpasabot nga wala nay bag-ong datos
Atong tan-awon ang usa ka demo:
Sa sinugdanan among iproseso ang mga kantidad 1, 2, 3, ug pagkahuman sa 1 segundos. makuha namo ang 4 ug tapuson among thread.
Naghunahuna og kusog
Ug dayon akong naamgohan nga mas makaiikag ang isulti kay sa pagsulat bahin niini. π
subscription
Kung nag-subscribe kami sa usa ka sapa, naghimo kami usa ka bag-ong klase subscription, nga naghatag kanamo og kapilian sa pag-unsubscribe sa pamaagi unsubscribe. Mahimo usab namo ang mga subskripsyon sa grupo gamit ang pamaagi sa pagdugang. Aw, makatarunganon nga mahimo naton i-ungroup ang mga thread gamit kuhaa. Ang mga paagi sa pagdugang ug pagtangtang nagdawat usa ka lahi nga suskrisyon ingon input. Gusto nakong timan-an nga kung mag-unsubscribe kami, mag-unsubscribe kami sa tanan nga mga subskripsyon sa bata ingon nga gitawag usab nila ang pamaagi sa pag-unsubscribe. Sige na nga.
Mga tipo sa sapa
HOT
GIPANGITA
Ang prodyuser gimugna sa gawas sa makita
Ang prodyuser gihimo sa sulod nga makita
Ang datos gipasa sa panahon nga ang naobserbahan gihimo
Ang datos gihatag sa panahon sa suskrisyon.
Nagkinahanglan og dugang nga lohika sa pag-unsubscribe
Ang thread natapos sa iyang kaugalingon
Gigamit ang usa-sa-daghan nga relasyon
Gigamit ang usa-sa-usa nga relasyon
Ang tanan nga mga suskrisyon adunay parehas nga kantidad
Ang mga suskrisyon kay independente
Mahimong mawala ang datos kung walay suskrisyon
Gi-isyu pag-usab ang tanan nga mga kantidad sa stream alang sa usa ka bag-ong suskrisyon
Sa paghatag ug analohiya, akong mahanduraw ang init nga sapa sama sa salida sa sinehan. Sa unsa nga punto sa imong pag-abut, gikan nianang higayona nagsugod ka sa pagtan-aw. Akong itandi ang usa ka bugnaw nga sapa sa usa ka tawag sa mga. suporta. Bisan kinsa nga nagtawag maminaw sa pagrekord sa answering machine gikan sa pagsugod hangtod sa pagkahuman, apan mahimo nimong ibitay ang pag-unsubscribe.
Gusto nakong timan-an nga adunay usab gitawag nga mainit nga mga sapa (akong nahimamat ang ingon nga kahulugan nga talagsa ra ug sa mga langyaw nga komunidad) - kini usa ka sapa nga nagbag-o gikan sa usa ka bugnaw nga sapa ngadto sa usa ka init. Ang pangutana mitungha - asa gamiton)) Maghatag ako usa ka pananglitan gikan sa praktis.
Nagtrabaho ko sa Angular. Aktibo siyang naggamit ug rxjs. Aron makuha ang data sa server, nagpaabut ko nga usa ka bugnaw nga sapa ug gigamit nako kini nga sapa sa template gamit ang asyncPipe. Kung gamiton nako kini nga tubo sa makadaghang higayon, nan, pagbalik sa kahulugan sa usa ka bugnaw nga sapa, ang matag tubo mangayo og datos gikan sa server, nga dili katingad-an nga isulti ang labing gamay. Ug kung akong i-convert ang usa ka bugnaw nga sapa ngadto sa usa ka mainit, nan ang hangyo mahitabo sa makausa.
Sa kinatibuk-an, ang pagsabut sa matang sa mga dagan lisud kaayo alang sa mga nagsugod, apan importante.
operators
return this.http.get(`${environment.apiUrl}/${this.apiUrl}/trade_companies`)
.pipe(
tap(({ data }: TradeCompanyList) => this.companies$$.next(cloneDeep(data))),
map(({ data }: TradeCompanyList) => data)
);
Ang mga operators naghatag kanamo ug higayon nga makatrabaho sa mga sapa. Nagtabang sila sa pagpugong sa mga panghitabo nga nagdagayday sa Observable. Atong hisgotan ang usa ka magtiayon nga labing inila, ug dugang nga kasayuran bahin sa mga operator makita sa mga link sa mapuslanon nga kasayuran.
Operators-sa
Magsugod ta sa helper operator sa. Naghimo kini og usa ka Observable base sa usa ka yano nga kantidad.
Mga operator-filter
Ang filter operator, ingon sa gisugyot sa ngalan, nagsala sa stream signal. Kung ang operator mobalik nga tinuod, nan kini molaktaw pa.
Mga operator - kuhaa
take - Gikuha ang kantidad sa gidaghanon sa mga emits, pagkahuman matapos ang sapa.
Operators-debounceTime
debounceTime - isalikway ang emitted values ββββnga nahulog sulod sa gitakda nga time interval tali sa output data - human ang time interval milabay, emits the last value.
Ang hiniusa nga operator combineLatest medyo susama sa promise.all. Gihiusa niini ang daghang mga sapa sa usa. Human ang matag hilo nakahimo ug labing menos usa ka emit, atong makuha ang pinakabag-o nga mga kantidad gikan sa matag usa isip array. Dugang pa, pagkahuman sa bisan unsang pagbuga gikan sa hiniusa nga mga sapa, maghatag kini mga bag-ong kantidad.
Zip - naghulat alang sa usa ka kantidad gikan sa matag sapa ug nagporma og usa ka laray base sa kini nga mga kantidad. Kung ang bili dili gikan sa bisan unsang hilo, nan ang grupo dili maporma.
Gitugotan ka sa tap operator nga maghimo mga side effect, nga mao, bisan unsang mga aksyon nga dili makaapekto sa pagkasunod-sunod.
Ang share utility operator makahimo sa usa ka bugnaw nga sapa ngadto sa usa ka init.
Ang mga operator nahuman na. Mopadayon ta sa Subject.
Naghunahuna og kusog
Ug dayon miadto ko sa pag-inom og tsa. Gikapoy nako ani nga mga pananglitan π
Pamilya sa subject
Ang pamilya sa hilisgutan usa ka panguna nga pananglitan sa mainit nga mga hilo. Kini nga mga klase usa ka klase nga hybrid nga naglihok ingon maobserbahan ug tigpaniid sa parehas nga oras. Tungod kay ang hilisgutan usa ka mainit nga sapa, kinahanglan kini nga i-unsubscribe. Kung maghisgot kita bahin sa mga nag-unang pamaagi, nan kini mao ang:
sunod - pagpasa sa bag-ong datos sa sapa
sayup - sayup ug pagtapos sa thread
kompleto - katapusan sa hilo
mag-subscribe - mag-subscribe sa usa ka sapa
unsubscribe - unsubscribe gikan sa sapa
asObservable - pagbag-o ngadto sa usa ka tigpaniid
toPromise - mausab ngadto sa usa ka saad
Paggahin ug 4 5 ka matang sa mga subject.
Naghunahuna og kusog
Giingon nako ang 4 sa sapa, apan nadugangan pa nila ang usa. Ingon sa giingon, mabuhi ug pagkat-on.
Simple nga Subject new Subject()- ang pinakasimple nga matang sa mga hilisgutan. Gihimo nga walay mga parameter. Gipasa ang mga kantidad nga moabut pagkahuman sa suskrisyon.
PanggawiSubject new BehaviorSubject( defaultData<T> ) - sa akong opinyon ang labing komon nga matang sa subject-s. Ang input nagkuha sa default nga kantidad. Kanunay nga i-save ang datos sa katapusan nga isyu, nga gipasa kung nag-subscribe. Kini nga klase usab adunay usa ka mapuslanon nga pamaagi sa kantidad nga nagbalik sa karon nga kantidad sa sapa.
ReplaySubject new ReplaySubject(bufferSize?: number, windowTime?: number) - Opsyonal, mahimo nga mahimong una nga argumento ang gidak-on sa buffer sa mga kantidad nga kini tipigan sa iyang kaugalingon, ug ang ikaduha nga higayon diin kinahanglan naton ang mga pagbag-o.
async nga subject new AsyncSubject() - wala'y mahitabo kung mag-subscribe, ug ang kantidad ibalik ra kung kompleto na. Ang kataposang bili lamang sa sapa ang ibalik.
WebSocketSubject new WebSocketSubject(urlConfigOrSource: string | WebSocketSubjectConfig<T> | Observable<T>, destination?: Observer<T>) - Ang dokumentasyon hilom bahin niini ug ako mismo nakakita niini sa unang higayon. Kinsa ang nahibal-an kung unsa ang iyang gibuhat, pagsulat, among idugang.
Phew. Aw, among gikonsiderar ang tanan nga gusto nakong isulti karon. Hinaot makatabang kini nga impormasyon. Mahimo nimong basahon ang lista sa literatura sa imong kaugalingon sa tab nga Mapuslanon nga Impormasyon.