Node nasce nel 2009 ed è un "Javascript runtime enviroment," ovvero, un' ambiente di esecuzione del codice, dove andiamo ad eseguire javascript al difuori del browser.
Infatti, con node, è stato prelevato il "Chrome V8 Engine", che è il motore (interprete) che permette al browser di eseguire codice javascript, ed è stato impacchettato in un applicazione C++, consentendoci così di eseguire codice Javascript sul nostro PC o su di un server.
(Browser) V8 Engine -> Applicazione C++ -> Funzionalità JS su PC e Server
Node.js è un runtime JavaScript enviroment costruito sul motore JavaScript V8 di Chrome che ha un single-thread event-loop (con annessa event-queue) non-blocking-code (gestione degli eventi async).
Per comprendere il funzionamento di Node.js dobbiamo trattare seppur superficialmente la differenza tra sistemi single thread e sistemi multi-thread.
Con la parola "thread" si fa riferimento al/ai numeri di processori di un sistema; mentre, con la parola "process" ci si riferisce ai processi intesi come esecuzione di operazioni.
In un sistema a singolo thread quando viene eseguita una chiamata bloccante, bocco di codice impegnativo a livello di calcolo, viene bloccato l’intero processo e solo al termine di quest'ultima il programma procederà con i successivi.
Un sistema multithread ha la possibilità di sfruttare il parallelismo, ovvero, di eseguire più processi contemporaneamente su differenti processori, percorsi di esecuzione.
Node.js è un sistema single thread definito event-loop, che, grazie alle proprietà del linguaggio javascript, funzione come, se non meglio, di un multi-thread;
Questo è possibile grazie ad un approccio asincrono ed al modello di sviluppo event-driven.
Il modello event-driven, o "programmazione ad eventi", si basa su un concetto molto semplice: si lancia una azione quando qualcosa accade; grazie alle "promise", strettamente legate all'asincrono e alle "callback", funzioni che sono eseguite dopo il termine di altre operazioni/funzioni, possiamo guidare/gestire l'ordine e la contemporaneità dell' esecuzione di determinate operazioni in modo da non bloccare (not-blocking-code) l'esecuzione del programma stesso in attesa dei risultati di operazioni, in ordine di scrittura del codice, antecedenti.
L'event-loop è una struttura di programmazione che verifica continuamente la presenza di eventi esterni e chiama le routine appropriate per gestirli.
Si tratta di un paradigma di programmazione.
Mentre in un programma tradizionale l'esecuzione delle istruzioni segue percorsi fissi, che si ramificano soltanto in punti ben determinati predefiniti dal programmatore, nei programmi scritti utilizzando la tecnica ad eventi il flusso del programma è largamente determinato dal verificarsi di eventi esterni.
Gli eventi seppur gestiti in maniera asincrona seguono quella che è chiamata "event-queue", tradotto, "coda-degli-eventi".
Gli eventi sono ordinati uno-dietro-l'altro ma nonostante ciò la restituzione del risultato è determinata dal tempo di esecuzione del compito stesso; questo consente lo svolgimento di più compiti contemporaneamente e la restituzione dei risultati nell'ordine di quanto sono impegnativi.
Node.js si basa su un modello Input/Output non bloccante basato su eventi.
Con il termine "blocking-code" ci si riferisce al blocco di ulteriori operazioni fino al termine dell'operazione in corso. I metodi di blocco vengono eseguiti in modo sincrono. Sincrono significa che il programma viene eseguito riga per riga. Il programma attende il ritorno della funzione chiamata o dell'operazione.
const fs = require('fs');
const filepath = 'text.txt';
// Reads a file in a synchronous and blocking way
const data = fs.readFileSync(filepath, {encoding: 'utf8'});
// Prints the content of file
console.log(data);
// This section calculates the sum of numbers from 1 to 10
let sum = 0;
for(let i=1; i<=10; i++){
sum = sum + i;
}
// Prints the sum
console.log('Sum: ', sum);
OUTPUT: Questo è da file di testo. Somma: 55
Con il termine "Non-Blocking-code" ci si riferisce al programma che non blocca l'esecuzione di ulteriori operazioni. I metodi non bloccanti vengono eseguiti in modo asincrono. Asincrono significa che il programma non esegue i comandi riga per riga. Il programma chiama la funzione e passa all'operazione successiva e non attende il suo ritorno.
const fs = require('fs');
const filepath = 'text.txt';
// Reads a file in a asynchronous and non-blocking way
fs.readFile(filepath, {encoding: 'utf8'}, (err, data) => {
// Prints the content of file
console.log(data);
});
// This section calculates the sum of numbers from 1 to 10
let sum = 0;
for(let i=1; i<=10; i++){
sum = sum + i;
}
// Prints the sum
console.log('Sum: ', sum);
OUTPUT: Somma: 55 Questo è da file di testo.