Introducció
En aquest tema, explorarem els conceptes de callbacks i programació asíncrona en Node.js. La programació asíncrona és una característica fonamental de Node.js que permet gestionar operacions d'entrada/sortida (I/O) de manera eficient sense bloquejar el fil principal d'execució.
Què és un Callback?
Un callback és una funció que es passa com a argument a una altra funció i que s'executa després que aquesta funció hagi completat la seva tasca. Els callbacks són essencials per a la programació asíncrona en Node.js.
Exemple de Callback
function saludar(nom, callback) { console.log('Hola, ' + nom + '!'); callback(); } function despedir() { console.log('Adéu!'); } saludar('Joan', despedir);
Explicació:
- Definim una funció
saludar
que accepta un nom i un callback. - La funció
saludar
imprimeix un missatge de salutació i després crida el callback. - Definim una funció
despedir
que imprimeix un missatge de comiat. - Cridem la funció
saludar
passant-li el nom 'Joan' i la funciódespedir
com a callback.
Programació Asíncrona
La programació asíncrona permet que el codi continuï executant-se mentre es realitzen operacions que poden trigar temps, com ara la lectura de fitxers o la consulta a una base de dades. Això és especialment important en Node.js, ja que utilitza un sol fil d'execució.
Exemple d'Operació Asíncrona
const fs = require('fs'); fs.readFile('fitxer.txt', 'utf8', (err, data) => { if (err) { console.error('Error llegint el fitxer:', err); return; } console.log('Contingut del fitxer:', data); }); console.log('Aquesta línia s\'executa abans que la lectura del fitxer es completi.');
Explicació:
- Utilitzem el mòdul
fs
per llegir un fitxer de manera asíncrona. - La funció
readFile
accepta un callback que es crida quan la lectura del fitxer es completa. - Si hi ha un error, es mostra un missatge d'error.
- Si la lectura és exitosa, es mostra el contingut del fitxer.
- La línia
console.log
fora dereadFile
s'executa immediatament, abans que la lectura del fitxer es completi.
Errors Comuns amb Callbacks
Callback Hell
Quan es fan moltes operacions asíncrones en seqüència, els callbacks poden anidar-se profundament, creant un codi difícil de llegir i mantenir. Això es coneix com a "callback hell".
Exemple de Callback Hell:
fs.readFile('fitxer1.txt', 'utf8', (err, data1) => { if (err) { console.error('Error llegint fitxer1:', err); return; } fs.readFile('fitxer2.txt', 'utf8', (err, data2) => { if (err) { console.error('Error llegint fitxer2:', err); return; } fs.readFile('fitxer3.txt', 'utf8', (err, data3) => { if (err) { console.error('Error llegint fitxer3:', err); return; } console.log('Contingut dels fitxers:', data1, data2, data3); }); }); });
Solució: Promises i Async/Await
Per evitar el "callback hell", es poden utilitzar Promises i la sintaxi async/await
.
Exemple amb Promises:
const fs = require('fs').promises; fs.readFile('fitxer1.txt', 'utf8') .then(data1 => { return fs.readFile('fitxer2.txt', 'utf8'); }) .then(data2 => { return fs.readFile('fitxer3.txt', 'utf8'); }) .then(data3 => { console.log('Contingut dels fitxers:', data1, data2, data3); }) .catch(err => { console.error('Error llegint els fitxers:', err); });
Exemple amb Async/Await:
const fs = require('fs').promises; async function llegirFitxers() { try { const data1 = await fs.readFile('fitxer1.txt', 'utf8'); const data2 = await fs.readFile('fitxer2.txt', 'utf8'); const data3 = await fs.readFile('fitxer3.txt', 'utf8'); console.log('Contingut dels fitxers:', data1, data2, data3); } catch (err) { console.error('Error llegint els fitxers:', err); } } llegirFitxers();
Exercicis Pràctics
Exercici 1: Callback Bàsic
Escriu una funció ferCalcul
que accepti dos números i un callback. La funció ha de sumar els dos números i passar el resultat al callback.
function ferCalcul(num1, num2, callback) { // Escriu el teu codi aquí } // Exemple d'ús: ferCalcul(5, 10, resultat => { console.log('El resultat és:', resultat); });
Solució:
function ferCalcul(num1, num2, callback) { const resultat = num1 + num2; callback(resultat); } // Exemple d'ús: ferCalcul(5, 10, resultat => { console.log('El resultat és:', resultat); });
Exercici 2: Lectura Asíncrona de Fitxers
Utilitza fs.readFile
per llegir el contingut de dos fitxers de manera asíncrona i mostrar el contingut combinat.
Solució:
const fs = require('fs'); function llegirFitxers() { fs.readFile('fitxer1.txt', 'utf8', (err, data1) => { if (err) { console.error('Error llegint fitxer1:', err); return; } fs.readFile('fitxer2.txt', 'utf8', (err, data2) => { if (err) { console.error('Error llegint fitxer2:', err); return; } console.log('Contingut combinat:', data1 + data2); }); }); } llegirFitxers();
Conclusió
En aquesta secció, hem après què són els callbacks i com s'utilitzen per a la programació asíncrona en Node.js. També hem vist com evitar el "callback hell" utilitzant Promises i async/await
. Aquests conceptes són fonamentals per escriure codi eficient i mantenible en Node.js. En el proper mòdul, explorarem els mòduls i la funció require()
per organitzar millor el nostre codi.
Curs de Node.js
Mòdul 1: Introducció a Node.js
Mòdul 2: Conceptes Bàsics
Mòdul 3: Sistema de Fitxers i I/O
Mòdul 4: HTTP i Servidors Web
Mòdul 5: NPM i Gestió de Paquets
Mòdul 6: Framework Express.js
- Introducció a Express.js
- Configuració d'una Aplicació Express
- Middleware
- Routing en Express
- Gestió d'Errors
Mòdul 7: Bases de Dades i ORMs
- Introducció a les Bases de Dades
- Utilitzar MongoDB amb Mongoose
- Utilitzar Bases de Dades SQL amb Sequelize
- Operacions CRUD
Mòdul 8: Autenticació i Autorització
Mòdul 9: Proves i Depuració
- Introducció a les Proves
- Proves Unitàries amb Mocha i Chai
- Proves d'Integració
- Depuració d'Aplicacions Node.js
Mòdul 10: Temes Avançats
Mòdul 11: Desplegament i DevOps
- Variables d'Entorn
- Utilitzar PM2 per a la Gestió de Processos
- Desplegar a Heroku
- Integració i Desplegament Continu