async / await operatorii face mai ușoară implementarea multor promisiuni asincronizate. De asemenea, permit inginerilor să scrie un cod mai clar, mai succint, testabil.

Pentru a înțelege acest subiect, ar trebui să aveți o înțelegere solidă a modului în care Promisiuni muncă.

Sintaxa de bază

function slowlyResolvedPromiseFunc(string) { 
  return new Promise(resolve => {
    setTimeout(() => {
      resolve(string);
    }, 5000);
  });
}

async function doIt() {
  const myPromise = await slowlyResolvedPromiseFunc("foo");
  console.log(myPromise); // "foo"
}

doIt();

Există câteva lucruri de remarcat:

  • Funcția care cuprinde await declarația trebuie să includă async operator. Aceasta va spune interpretului JS că trebuie să aștepte până când Promisiunea este rezolvată sau respinsă.
  • await operatorul trebuie să fie în linie, în timpul declarației const.
  • Acest lucru funcționează pentru reject precum și resolve.

Promisiuni imbricate vs. Async / Await

Implementarea unei singure promisiuni este destul de simplă. În schimb, Promisiunile înlănțuite sau crearea unui model de dependență pot produce „cod spaghetti”.

Următoarele exemple presupun că request-promise biblioteca este disponibilă ca rp.

ad-banner

Promisiuni înlănțuite / imbricate

// First Promise
const fooPromise = rp("http://domain.com/foo");

fooPromise.then(resultFoo => {
    // Must wait for "foo" to resolve
    console.log(resultFoo);

    const barPromise = rp("http://domain.com/bar");
    const bazPromise = rp("http://domain.com/baz");

    return Promise.all([barPromise, bazPromise]);
}).then(resultArr => {
    // Handle "bar" and "baz" resolutions here
    console.log(resultArr[0]);
    console.log(resultArr[1]);
});

async și await Promisiuni

// Wrap everything in an async function
async function doItAll() {
    // Grab data from "foo" endpoint, but wait for resolution
    console.log(await rp("http://domain.com/foo"));

    // Concurrently kick off the next two async calls,
    // don't wait for "bar" to kick off "baz"
    const barPromise = rp("http://domain.com/bar");
    const bazPromise = rp("http://domain.com/baz");

    // After both are concurrently kicked off, wait for both
    const barResponse = await barPromise;
    const bazResponse = await bazPromise;

    console.log(barResponse);
    console.log(bazResponse);
}

// Finally, invoke the async function
doItAll().then(() => console.log('Done!'));

Avantajele utilizării async și await ar trebui să fie clar. Acest cod este mai lizibil, modular și testabil.

Este corect să observăm că, deși există un sentiment adăugat de concurență, procesul de calcul subiacent este același cu exemplul anterior.


Tratarea erorilor / respingere

Un bloc de bază try-catch gestionează o promisiune respinsă.

async function errorExample() {
  try {
    const rejectedPromise = await Promise.reject("Oh-oh!");
  } catch (error) {
    console.log(error); // "Uh-oh!"
  }
}

errorExample();