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ó:

  1. Definim una funció saludar que accepta un nom i un callback.
  2. La funció saludar imprimeix un missatge de salutació i després crida el callback.
  3. Definim una funció despedir que imprimeix un missatge de comiat.
  4. 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ó:

  1. Utilitzem el mòdul fs per llegir un fitxer de manera asíncrona.
  2. La funció readFile accepta un callback que es crida quan la lectura del fitxer es completa.
  3. Si hi ha un error, es mostra un missatge d'error.
  4. Si la lectura és exitosa, es mostra el contingut del fitxer.
  5. La línia console.log fora de readFile 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.

const fs = require('fs');

function llegirFitxers() {
    // Escriu el teu codi aquí
}

llegirFitxers();

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

Mòdul 7: Bases de Dades i ORMs

Mòdul 8: Autenticació i Autorització

Mòdul 9: Proves i Depuració

Mòdul 10: Temes Avançats

Mòdul 11: Desplegament i DevOps

Mòdul 12: Projectes del Món Real

© Copyright 2024. Tots els drets reservats