Cosa sono in JavaScript async e await e come cambia l’ uso delle Promise

Le Promise permettono di fare asynchronous operation, async e await estendono le Promise e danno la possibilità di scrivere codice maggiormente leggibile come fosse sincrono

Image for post
Image for post

Introduzione

Ma procediamo per gradi. Prima dell’avvento delle Promise le asynchronous operation dovevano essere fatte attraverso l’uso dei callback. Le Promise hanno poi introdotto il concetto di chaining che permette di concatenare i vari metodi: .then() e .catch(). In questo modo non si vedono più tutti quei callback annidati che rendendo il codice poco leggibile.

Image for post
Image for post

Con l’avvento di “async” e “await” lavoriamo sempre con le Promise, ma non siamo più obbligati ad avere il chaining. Il risultato finale sarà del codice che pur rimanendo asincrono, all’apparenza e come codice sincrono questo a scapito di una maggiore leggibilità. Per chi conosce .Net abbiamo le stesse funzionalità fornite dalle keywords“async” e “await” in C#

Image for post
Image for post

Async

Caso 1

async function f() {  return 1;}f().then(alert); // 1

Caso 2

async function f() {  return Promise.resolve(1);}f().then(alert); // 1

Await

Cosa molto importante può essere usata solo all’interno di una funzione decorata con “async”. Se la funzione non è decorata con “async”, non funziona!

async function f() {  let promise = new Promise((resolve, reject) => {    setTimeout(() => resolve(“done!”), 1000)  });  let result = await promise; // wait until the promise resolves (*)  alert(result); // “done!”}f();

L’esecuzione della funzione verrà messa in pausa alla linea (*) e verrà ripresa quando la Promise ritornerà il risultato. A questo punto verrà mostrato “done!”. Come detto questo non bloccherà il thread, dietro alla quinte è comunque eseguita in modo asincrono.

Errori

async function f() {  try {    let response = await fetch(‘http://no-such-url');  } catch(err) {    alert(err); // TypeError: failed to fetch  }}f();

I 2 spezzoni di codice sottostante sono equivalenti.

async function f() {  await Promise.reject(new Error(“Whoops!”));}async function f() {  throw new Error(“Whoops!”);}

Se omettiamo di inserire un blocco catch otterremo un “unhandled error” visibile nella console.

Vediamo un esempio più complesso

function who() {  return new Promise(resolve => {
setTimeout(() => {
resolve(' Robin Hood ');
}, 300);
});}function what() { return new Promise(resolve => {
setTimeout(() => {
resolve('è un personaggio dei fumetti');
}, 300);
});}function where() { return new Promise(resolve => {
setTimeout(() => {
resolve('e vive nel bosco');
}, 300);
});}async function msg() {
const a = await who();
const b = await what();
const c = await where();
console.log(`${ a } ${ b } ${ c }`);
}
msg(); // Robin Hood è un personaggio dei fumetti e vive nel bosco -
// after 900 msec

Nell’esempio sovrastante ciascun step viene eseguito sequenzialmente, ogni step attenderà che venga fornita la risposta dello step precedente. Se volessimo un’esecuzione parallela dovremmo modificarlo nel seguente modo.

async function msg() {
const [a, b, c] = await Promise.all([who(), what(), where()]);
console.log(`${ a } ${ b } ${ c }`);
}
msg(); // Robin Hood è un personaggio dei fumetti e vive nel bosco
// after 300 msec

Il metodo Promise.all() ritorna un array di valori risolti.

Conclusioni

IMPORTANTE: Quello scritto nel presente articolo con un browser vecchio non vale perchè le Promise non sono supportate. Per cui non rimane che fare le asynchronous operation alla vecchia maniera: ovvero con le callback!

Per approfondire: Cosa sono le JavaScript Promise e cos’è il chaining

Se volete contattarmi il mio profilo Linkedin è il seguente: Stefano Marchisio: Consulente freelance Angular ASP.NET MVC C#

Sono uno sviluppatore web full-stack: Angular / TypeScript e ASP.NET MVC CORE C# https://www.stefanomarchisio.it/

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store