Ievads promisos JavaScript
Jūs jau zināt, ka atsauksmes (callback) modeļa izmantošana asinhronitātei viegli noved pie situācijas callback hell. Tāpēc JavaScript tika ieviests jauns modelis ar nosaukumu promisi (promise). Izpētīsim šo modeli.
Promiss ir objekts, kurā kā parametrs tiek padota funkcija, kuras iekšpusē jāievieto mūsu asinhronais kods:
let promise = new Promise(function() {
// asinhronais kods
});
Kā redzat, es ierakstīju objektu ar promisu
mainīgajā promise. Kādā citā kodā
es varu izmantot šo mainīgo
metodi then, padodot tai funkciju
ar kodu, kas jāizpilda pēc
asinhronā koda pabeigšanas, kas uzrakstīts
šī promisa izveides laikā:
promise.then(function() {
// izpildīsies, kad asinhronais kods beidzas
});
Tas izklausās mulsinoši, tāpēc apskatīsim piemēru. Pieņemsim, ka man ir šāds asinhronais kods:
setTimeout(function() {
let result = [1, 2, 3, 4, 5];
}, 3000);
Pieņemsim, ka es vēlos atrisināt tam mūsu galveno
asinhronitātes problēmu: izpildīt kādu
kodu pēc taimera izsaukšanas. Turklāt
es nevēlos ievietot šo kodu pašā taimerī
un vēlos, lai šajā kodā kaut kā nonāktu rezultāts,
ko es ierakstīju mainīgajā result.
Principā mēs šo problēmu atrisinājām iepriekšējās
nodarbībās, izmantojot atsauksmes (callbacks) un abonementus. Tagad
apskatīsim, kā to izdarīt, izmantojot promisus.
Vispirms mūsu asinhronais kods jāievieto promisā:
let promise = new Promise(function() {
setTimeout(function() {
let result = [1, 2, 3, 4, 5];
}, 3000);
});
Tomēr ar to nepietiek. Mums ir jānorāda skaidri, ka mūsu asinhronais kods ir pabeigts. Tas mums palīdzēs īpaša pabeigšanas funkcija, kas automātiski nonāk pirmajā funkcijas parametrā, ja tas ir norādīts:
let promise = new Promise(function(resolve) { // norādām parametru
setTimeout(function() {
let result = [1, 2, 3, 4, 5];
}, 3000);
});
Izmantojot pabeigšanas funkciju, mēs varam skaidri norādīt promisam, ka asinhronais kods ir pabeigts. Lai to izdarītu, mums šī funkcija jāizsauc vajadzīgajā vietā:
let promise = new Promise(function(resolve) {
setTimeout(function() {
let result = [1, 2, 3, 4, 5];
resolve(); // pabeidzam promisu
}, 3000);
});
Turklāt, ja mēs vēlamies kaut kādu asinhronā koda rezultātu nodot ārēji, mēs to varam padot kā parametru mūsu pabeigšanas funkcijai:
let promise = new Promise(function(resolve) {
setTimeout(function() {
let result = [1, 2, 3, 4, 5];
resolve(result); // nododam rezultātu
}, 3000);
});
Protams, var atbrīvoties no starpmainīgā:
let promise = new Promise(function(resolve) {
setTimeout(function() {
resolve([1, 2, 3, 4, 5]);
}, 3000);
});
Tagad jebkurā citā vietā mēs varam izsaukt
mūsu promisa metodi then:
promise.then(function() {
// darbosies, kad promiss pabeigts
});
Promisa darbības rezultāts nonāks pirmajā funkcijas parametrā, ja mēs vēlēsimies to norādīt:
promise.then(function(result) {
console.log(result); // izvadīs masīvu ar rezultātu
});
Izveidojiet promisu, kura iekšpusē būs kavēšanās
5 sekundes, pēc kuras promisam jāizpildās, atgriežot kādu tekstu kā savu rezultātu.
Izvadiet šo tekstu uz ekrāna.