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ó
saludarque accepta un nom i un callback. - La funció
saludarimprimeix un missatge de salutació i després crida el callback. - Definim una funció
despedirque imprimeix un missatge de comiat. - Cridem la funció
saludarpassant-li el nom 'Joan' i la funciódespedircom 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
fsper llegir un fitxer de manera asíncrona. - La funció
readFileaccepta 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.logfora dereadFiles'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
