I'm trying to implement promises and async/await in my project. I need to use fetch to post some data to server and then do other processes using javascript. but I'm confused on how I should handle the error for nested async/await promises.
the problem is that there's an error "Uncaught (in promise) stop!!" and the string "stop!!" doesn't get added into the div
here's what I tried:
function tunggu(waktu) {
return new Promise((resolve) => {
const action = setTimeout(() => {
const str = `${waktu.toString()} milisecond has passed<br/>`;
resolve(str);
}, waktu);
})
}
const div = document.querySelector('#asd');
fetch('https://jsonplaceholder.typicode.com/todos/1')
.then(response => response.json())
.then(json => {
console.log(json);
(async () => {
div.innerHTML = 'start<br/>';
const a = await tunggu(2000);
div.innerHTML = a;
throw('stop!!'); // it looks like this line is causing the error
const b = await tunggu(3000);
div.innerHTML = b;
})();
})
.catch(error => {
console.log('error occurred', error)
div.innerHTML = error
})
<div id="asd"></div>
This (also on jsfiddle) is only a simplified version of my code, in my project the fetch uses the method POST, and the js processes actually have many more process in it so I used throw
in it because the error may occur in any place.
CodePudding user response:
there was an error "Uncaught (in promise) stop!!" and the string "stop!!" doesn't get added to the div
You broke the promise chain by introducing a stand-alone async function in the .then()
handler (which throws, but has no .catch()
of its own, which ultimately causes the error you see).
Instead, make the entire .then()
handler async:
function tunggu(waktu) {
return new Promise((resolve) => {
setTimeout((() => resolve(`${waktu.toString()} milisecond has passed`)), waktu);
})
}
const div = document.querySelector('#asd');
fetch('https://jsonplaceholder.typicode.com/todos/1')
.then(response => response.json())
.then(async (json) => {
console.log(json);
div.innerHTML = 'start<br/>';
const a = await tunggu(2000);
div.innerHTML = a '<br/>';
throw('stop!!');
const b = await tunggu(3000);
div.innerHTML = b;
})
.catch(error => {
console.log('error occurred', error)
div.innerHTML = error
})
<div id="asd"></div>
Alternatively, return the promise from your async IIFE, to keep the promise chain intact:
function tunggu(waktu) {
return new Promise((resolve) => {
setTimeout((() => resolve(`${waktu.toString()} milisecond has passed`)), waktu);
})
}
const div = document.querySelector('#asd');
fetch('https://jsonplaceholder.typicode.com/todos/1')
.then(response => response.json())
.then(json => {
console.log(json);
return (async () => {
div.innerHTML = 'start<br/>';
const a = await tunggu(2000);
div.innerHTML = a '<br/>';
throw('stop!!');
const b = await tunggu(3000);
div.innerHTML = b;
})();
})
.catch(error => {
console.log('error occurred', error)
div.innerHTML = error
})
<div id="asd"></div>