Introducere în promisiunile în JavaScript
Sunteți deja familiarizați cu faptul că utilizarea modelului de asincronitate cu callback-uri conduce ușor la situația numită callback hell. De aceea, în JavaScript a fost introdus un nou model numit promisiuni (promise). Să studiem acest model.
O promisiune reprezintă un obiect, căruia i se transmite ca parametru o funcție, în interiorul căreia trebuie să plasăm codul nostru asincron:
let promise = new Promise(function() {
// cod asincron
});
După cum vedeți, am stocat obiectul cu promisiunea
în variabila promise. Într-un alt loc
al codului, pot aplica acestei variabile
metoda then, transmitând în ea o funcție
cu codul care trebuie executat la
finalizarea codului asincron, scris
la crearea acestei promisiuni:
promise.then(function() {
// se execută la finalizarea codului asincron
});
Sună confuz, așa că să ne uităm la un exemplu. Să presupunem că am următorul cod asincron:
setTimeout(function() {
let result = [1, 2, 3, 4, 5];
}, 3000);
Să presupunem că vreau să rezolv pentru el
problema principală a asincronității: să execut un anumit
cod după declanșarea timer-ului. În același timp,
nu doresc să plasez acest cod în timer-ul însuși
și doresc ca în acest cod să ajungă cumva rezultatul,
scris de mine în variabila result.
În principiu, am rezolvat această problemă în lecțiile anterioare
prin callback-uri și abonamente. Să
vedem acum cum se face acest lucru folosind promisiuni.
Pentru început, trebuie să împachetăm codul nostru asincron într-o promisiune:
let promise = new Promise(function() {
setTimeout(function() {
let result = [1, 2, 3, 4, 5];
}, 3000);
});
Acest lucru, însă, nu este suficient. Trebuie să indicăm în mod explicit că codul nostru asincron s-a finalizat. În acest sens, ne va ajuta o funcție specială de finalizare, care ajunge automat în primul parametru al funcției, dacă acesta este specificat:
let promise = new Promise(function(resolve) { // specificăm parametrul
setTimeout(function() {
let result = [1, 2, 3, 4, 5];
}, 3000);
});
Cu ajutorul funcției de finalizare, putem indica în mod explicit promisiunii că codul asincron s-a finalizat. Pentru aceasta, trebuie să apelăm această funcție în locul dorit:
let promise = new Promise(function(resolve) {
setTimeout(function() {
let result = [1, 2, 3, 4, 5];
resolve(); // finalizăm promisiunea
}, 3000);
});
În același timp, dacă dorim să transmitem în exterior un anumit rezultat al codului asincron, îl putem transmite ca parametru al funcției noastre de finalizare:
let promise = new Promise(function(resolve) {
setTimeout(function() {
let result = [1, 2, 3, 4, 5];
resolve(result); // transmitem rezultatul
}, 3000);
});
Se poate, desigur, să renunțăm la variabila intermediară:
let promise = new Promise(function(resolve) {
setTimeout(function() {
resolve([1, 2, 3, 4, 5]);
}, 3000);
});
Acum în orice alt loc putem apela
metoda then a promisiunii noastre:
promise.then(function() {
// se va declanșa la finalizarea promisiunii
});
Rezultatul execuției promisiunii va ajunge în primul parametru al funcției, dacă dorim să îl specificăm:
promise.then(function(result) {
console.log(result); // va afișa matricea cu rezultatul
});
Creați o promisiune, în interiorul căreia să existe o întârziere
de 5 secunde, după care promisiunea trebuie să
se finalizeze, returnând ca rezultat propriu un text oarecare.
Afișați acest text pe ecran.