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