webroad.online
  1. 1Web
  2. 2HTML
  3. 3CSS
  4. 4JavaScript
  5. 5TypeScript
  6. 6Git
  7. 7Unelte
  8. 8React
  9. 9State management
  10. 10Next.js
  11. 11Formulare
  12. 12Date și backend
  13. 13SEO
  14. 14Tailwind CSS
  15. 15Animații
  16. 16Testare
  17. 17Arhitectură
JavaScript · Lecția 14 din 17

Async: Promise și await

Event loop, async/await, rulare în paralel cu Promise.all.

Actualizat

Ce înseamnă sincron și asincron

Sincron = fiecare linie așteaptă ca cea dinainte să termine. Asincron = pornești o operație lentă (request în rețea, timer, citire de fișier) și continui cu altceva; rezultatul vine mai târziu.

De ce contează: JS din browser rulează pe un singur thread — același care desenează pagina și răspunde la click-uri. Dacă ar aștepta sincron 2 secunde un request, pagina ar îngheța 2 secunde.

Event loop — cum funcționează

  1. Call stack — codul care rulează acum.
  2. Operațiile lente sunt date browserului (rețea, timere), care le face în paralel.
  3. Când una termină, callback-ul ei intră într-o coadă.
  4. Event loop-ul ia din coadă doar când stack-ul e gol.

Există două cozi, cu priorități diferite:

Coadă Ce intră Prioritate
microtask .then de Promise, await, queueMicrotask toate rulează înainte de următorul macrotask
macrotask setTimeout, setInterval, evenimente, I/O una pe tur
console.log(1)
setTimeout(() => console.log(4))          // macrotask
Promise.resolve().then(() => console.log(3)) // microtask
console.log(2)
// 1, 2, 3, 4

Ce este un Promise

Un Promise e un obiect care reprezintă o valoare care va veni — ca un bon de comandă: încă n-ai mâncarea, dar ai ceva ce poți aștepta.

Un Promise are 3 stări:

Stare Înseamnă
pending încă se lucrează
fulfilled gata, are o valoare
rejected a eșuat, are o eroare

O dată ce s-a terminat (fulfilled sau rejected), starea nu se mai schimbă.

const wait = ms => new Promise(resolve => setTimeout(resolve, ms))

fetch('/api/user')
  .then(res => res.json())      // rulează la succes
  .then(user => render(user))
  .catch(err => showError(err)) // rulează la eroare, oriunde în lanț

async / await — același lucru, scris ca sincron

async function loadUser(id) {
  try {
    const res = await fetch(`/api/users/${id}`)   // „pune pauză” funcției până vine răspunsul
    return await res.json()
  } catch (error) {
    return null
  }
}
  • async în fața funcției → returnează mereu un Promise.
  • await → așteaptă un Promise fără să blocheze pagina (doar funcția curentă „stă”).
  • Erorile se prind cu try/catch normal.
.then() async/await
Lizibilitate lanțuri, callback-uri cod de sus în jos
Erori .catch() try/catch
Când pipeline-uri scurte, în afara funcțiilor async implicit

Secvențial vs paralel — cea mai frecventă optimizare

// ✗ secvențial — al doilea pornește după primul: 2 × timpul
const user = await getUser()
const posts = await getPosts()

// ✓ paralel — pornesc amândouă deodată
const [user, posts] = await Promise.all([getUser(), getPosts()])

Folosește secvențial doar când al doilea request depinde de rezultatul primului.

Combinatorii de Promise — tipuri și când

Metodă Se termină când Dacă unul eșuează Când
Promise.all toate reușesc eșuează imediat ai nevoie de toate rezultatele
Promise.allSettled toate termină nu eșuează; primești statusul fiecăruia vrei rezultatele parțiale
Promise.race primul termină (oricum) depinde de primul timeout
Promise.any primul reușește eșuează doar dacă toate eșuează mai multe surse, oricare e bună

Greșeli clasice

  • forEach cu async nu așteaptă → for...of (secvențial) sau Promise.all(arr.map(...)) (paralel).
  • Uiți await → ai un Promise în loc de valoare (user.name e undefined).
  • Promise fără catch / try → unhandledrejection.
  • await în buclă când request-urile sunt independente → lent.

Pe scurt

  • JS are un singur thread; operațiile lente sunt asincrone ca pagina să nu înghețe.
  • Promise = valoare viitoare: pending → fulfilled / rejected.
  • async/await + try/catch; Promise.all pentru paralel.

Surse oficiale

Exerciții

Ți-a fost utilă pagina?

Un click — fără cont.