7.1 Utilizzo dei callback
La gestione degli errori è un aspetto importante della scrittura di codice affidabile e resistente ai guasti. Nel codice JavaScript asincrono, gli errori possono verificarsi sia nelle operazioni sincrone che asincrone. Una corretta gestione degli errori aiuta a evitare guasti imprevisti e offre agli utenti messaggi di errore utili. Esaminiamo alcuni metodi di gestione degli errori nel codice asincrono, inclusi i callback, le promise e async/await.
Prima dell'arrivo delle promise e di async/await, il codice asincrono veniva spesso implementato utilizzando i callback. In questo approccio, gli errori vengono passati al callback come primo argomento.
Esempio:
function fetchData(callback) {
setTimeout(() => {
const error = Math.random() > 0.5 ? new Error('Failed to fetch data') : null;
const data = error ? null : { id: 1, name: 'John Doe' };
callback(error, data);
}, 1000);
}
fetchData((error, data) => {
if (error) {
console.error('Error:', error);
} else {
console.log('Data:', data);
}
});
7.2 Utilizzo delle promise
Gestione degli errori con le promise
Le promise forniscono un modo più strutturato per lavorare con il codice asincrono. Gli errori vengono gestiti tramite il metodo catch.
Esempio:
function fetchData() {
return new Promise((resolve, reject) => {
setTimeout(() => {
const error = Math.random() > 0.5 ? new Error('Failed to fetch data') : null;
if (error) {
reject(error);
} else {
resolve({ id: 1, name: 'John Doe' });
}
}, 1000);
});
}
fetchData()
.then(data => console.log('Data:', data))
.catch(error => console.error('Error:', error));
Gestione degli errori con async/await
async/await offre un modo sintatticamente conveniente per lavorare con il codice asincrono, rendendolo più leggibile e simile al codice sincrono. Gli errori nelle funzioni asincrone possono essere gestiti tramite la struttura try...catch.
Esempio:
async function fetchData() {
return new Promise((resolve, reject) => {
setTimeout(() => {
const error = Math.random() > 0.5 ? new Error('Failed to fetch data') : null;
if (error) {
reject(error);
} else {
resolve({ id: 1, name: 'John Doe' });
}
}, 1000);
});
}
async function loadData() {
try {
const data = await fetchData();
console.log('Data:', data);
} catch (error) {
console.error('Error:', error);
}
}
loadData();
7.3 Gestione globale degli errori
Per gestire globalmente gli errori nel codice asincrono, puoi usare window.onError e window.onUnhandledRejection.
Esempio per window.onError:
window.onerror = function (message, source, lineno, colno, error) {
console.error('Global error handler:', error);
};
setTimeout(() => {
throw new Error('Test error');
}, 1000);
Esempio per window.onunhandledrejection:
window.onunhandledrejection = function (event) {
console.error('Unhandled rejection:', event.reason);
};
Promise.reject(new Error('Test unhandled rejection'));
7.4 Esempi di utilizzo
1. Richieste HTTP asincrone con Fetch e gestione degli errori:
async function fetchData() {
try {
const response = await fetch('https://jsonplaceholder.typicode.com/posts/1');
if (!response.ok) {
throw new Error('Network response was not ok');
}
const data = await response.json();
console.log('Data:', data);
} catch (error) {
console.error('Fetch error:', error);
}
}
fetchData();
2. Esecuzione parallela delle richieste con Promise.all e gestione degli errori:
async function fetchMultipleData() {
try {
const [response1, response2] = await Promise.all([
fetch('https://jsonplaceholder.typicode.com/posts/1'),
fetch('https://jsonplaceholder.typicode.com/posts/2')
]);
if (!response1.ok || !response2.ok) {
throw new Error('One of the responses was not ok');
}
const data1 = await response1.json();
const data2 = await response2.json();
console.log('Data 1:', data1);
console.log('Data 2:', data2);
} catch (error) {
console.error('Fetch multiple data error:', error);
}
}
fetchMultipleData();
GO TO FULL VERSION