Asynchronous JavaScript

Come gestire la concorrenza in JS

Nicola Zambello

Frontend developer @ RedTurtle

Studente @ UniFe

@nicolazambello

nzambello

nzambello @ italiajs.slack.com

Roadmap

0.  Event loop

1.  Callbacks

2.  Promise

3.  Generatori

4.  async / await

Event loop

Event loop

Come funziona JavaScript:

  • single thread
  • call stack

Event loop

Event loop - esempio

console.log('Hi');

setTimeout(function cb1() {
   console.log('cb1');
}, 5000);

console.log('Bye');

Event loop - esempio

Event loop - esempio

Event loop - esempio

Event loop - esempio

Event loop - esempio

Event loop - esempio

Event loop - esempio

Event loop - esempio

Event loop - esempio

Event loop - esempio

Event loop - esempio

Event loop - esempio

Event loop - esempio

Event loop - esempio

Event loop - esempio

Event loop - esempio

Callbacks

Callbacks

Una callback è una funzione passata ad un’altra funzione come parametro, all’interno della quale essa verrà chiamata.

Callbacks - esempio

$('#btn1').click(function() {
  alert('Btn 1 Clicked');
});

Callbacks - esempio

var friends = ['Mike', 'Stacy', 'Andy', 'Rick'];

friends.forEach(function(eachName, index) {
  console.log(index + 1 + '. '.concat(eachName));​
});
// 1. Mike, 2. Stacy, 3. Andy, 4. Rick

Callbacks

  • Callback hell
  • Inversione del controllo
  • Perdita dello scope

 rischi e pericoli

Callbacks

 rischi e pericoli

Callback hell:

  • Callback annidate
  • Spesso poco comprensibili
  • Difficili da gestire in debug
getData(function (a) {
  getMoreData(a, function (b) {
    getMoreData(b, function (c) {
      getMoreData(c, function (d) {
        getMoreData(d, function (e) {
          console.log('Callback Hell');
        });
      });
    });
  });
});

Promises

Promises

Le promises sono definite come “una delega (proxy) per un valore che - in qualche momento - diventerà disponibile”.

ES 6

Promises - stato

Le promises possono essere in 3 stati:

  • pending (default)
  • fulfilled
  • rejected

Promise - esempio

asyncFunc1()
  .then(asyncFunc2)
  .then(asyncFunc3)
  .catch(err => {
    // ERROR!
  })

Promise - esempio

fetch(apiURL).then(
    res => {
        // handle response
    },
    err => {
        // handle error
    }
)

Promises

Demo time!

Generatori

Generatori

I generatori sono funzioni dalle quali è possibile uscire e poi rientrarvi in un secondo momento.

ES 6

Generatori

Due importanti applicazioni dei generatori sono:

  • Implementazione di iterables
  • Blocco di chiamate a funzioni asincrone

Internet Explorer

Generatori - esempi

const genFunc = function* () { ··· };
let genObj = genFunc();
let obj = {
    * generatorMethod() {
        ···
    }
};
let genObj = obj.generatorMethod();
class MyClass {
    * generatorMethod() {
        ···
    }
}
let myInst = new MyClass();
let genObj = myInst.generatorMethod();

Generatori - utilizzi

I generatori possono essere utilizzati principalmente in 3 modi:

  • Iterators (data producers)
    • for … of
    • spread operator
  • Observers (data consumers)
  • Coroutines (data producers and consumers)

 

 

Generatori

Demo time!

async functions

async functions

Quando viene chiamata una funzione async, viene restituita una Promise.

Quando la funzione async restituisce un valore, la Promise verrà risolta con il valore restituito.

Quando la funzione async genera un'eccezione o un valore, la Promise verrà rifiutata con il valore generato.

ES 7

async functions

Una funzione async può contenere un'espressione await, che sospende l'esecuzione della funzione async e attende la risoluzione della Promise, quindi riprende l'esecuzione della funzione async e restituisce il valore risolto.

async functions

Demo time!

async functions

attenzione

Occhio al async nella callback di map()

async function getAllFiles (fileNames) {
    return await* fileNames.map(async function(fileName) {
        var file = await getFileAsync(fileName);
        return parse(file);
    });
}

Grazie!