martedì, novembre 25, 2014

Programmazione asincrona e callbacks

Una analogia per capire la differenza tra programmazione sincrona e asincrona.
Normalmente gli uomini si comportano in maniera sincrona, le donne in modo asincrono :))
Quando faccio il caffè al mattino, aspetto quei 4 secondi davanti alla tazzina che si riempie.
Mia moglie, durante quei 4 secondi magari comincia a svuotare la lavastoviglie.

In java, normalmente, l'esecuzione delle istruzioni avviene in maniera sincrona, una istruzione viene eseguita non prima che la precedente abbia finito; se si vuole una sorta di parallelismo, bisogna usare i threads, con tutto il sovracarico (overhead), in termini di risorse, che ne consegue.

In javascript non esistono i threads. Tutte le nostre istruzioni vengono eseguite, sempre, in un unico thread ma esiste la possibilità di eseguire le istruzione in modalità asincrona.

Consideriamo lo scenario in cui dobbiamo effettuare una richiesta ad un server.

In modalità sincrona avremmo ad esempio

 richiesta = preparaRichiesta();  
 risposta = mandaRichiestaSincrona(richiesta);  
 visualizza(risposta);  

Se il server impiega 10 secondi a rispondere, il nostro codice è bloccato alla seconda istruzione, non si possono eseguire altre istruzioni nel frattempo.

In modalità asincrona avremmo invece, grazie alla possibilità di passare una funzione come parametro

 richiesta = preparaRichiesta();  
 mandaRichiestaAsincrona(richiesta, function(risposta) {  
   visualizza(risposta);  
 });  
 visualizza("Siamo in attesa di risposta dal server ...");  

In questo caso, la seconda istruzione è asincrona, dopo la sua esecuzione, il nostro programma continua con l'istruzione successiva: quando il server risponderà, con i suoi tempi, verrà eseguita la funzione di callback passata come argomento alla funzione asincrona.

Tecnicamente, il supporto alla programmazione asincrona è implementato, nell'interprete javascript, tramite l'utilizzo di

  • una coda di messaggi
  • un ciclo principale di gestione eventi
Tutte le istruzioni che devono essere eseguite dal nostro programma vengono inserite in una coda di messaggi che viene gestita da un ciclo principale che svuota ed esegue, in un unico thread, le istruzioni presenti nella coda.

Nel caso di una funzionalità asincrona, dipendente da un evento esterno al nostro programma, un componente del runtime di javascript aggiunge alla coda dei messaggi la funzione di callback da eseguire, con i relativi parametri, non appena l'evento si è verificato.

Le funzioni di callback non sono mai interrompibili, così come qualsiasi funzione in javascript: in questo modo non esite mai un problema di accesso ad aree di memorie condivise da thread diversi, visto che il ciclo principale viene eseguito in un unico thread.

Avrete già sentito l'acronimo AJAX: Asynchronous Javascript And Xml: è una tecnica che permette di effettuare richieste http ad un server in modalità asincrona, sfruttando il meccanismo visto sopra: quando il server risponde, viene eseguita la funzione di callback registrata con la richiesta, che, tipicamente, modifica il DOM (Document Object Model) della pagina html corrente.

Il DOM non è altro che la rappresentazione, ad albero, in memoria, del documento html.


Una sua modifica potrebbe essere, ad esempio, la creazione di una tabella con i dati restituiti dal server.

L'utente, mentre il server risponde, ha ancora la possibilità di interagire con la pagina corrente, generando eventi che possono essere gestiti dal ciclo principale in attesa della risposta del server.

E l'XML che c'entra? Storicamente era il formato scelto per rappresentare i dati scambiati tra client e server. Ora si preferisce il formato JSON e provate ad indovinare un pò il perche ...

Più in la, vedremo come implementare richieste asincrone a componenti lato server, componenti ovviamente implementati in javascript grazie alla piattaforma nodejs ;)

Alla prox.
Ivan

















2 commenti:

  1. Ora si preferisce il formato JSON e provate ad indovinare un pò il perche ..
    perché ?

    RispondiElimina
  2. JSON,JavaScript Object Notation, è un formato che rappresenta i dati così come sono rappresentati gli oggetti in javascript: è molto più semplice "elaborare" lato client i dati che arrivano dal server in notazione JSON e, inoltre, il formato è molto più snello: a parità di informazione il numero di byte trasferiti è minore.
    Ciao!
    Ivan

    RispondiElimina