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:

javascriptlet 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:

javascriptpromise.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:

javascriptsetTimeout(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:

javascriptlet 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:

javascriptlet 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:

javascriptlet 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:

javascriptlet 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ă:

javascriptlet 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:

javascriptpromise.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:

javascriptpromise.then(function(result) {
  console.log(result); // va afișa matricea cu rezultatul
});
Задание 1

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.