async와 await를 사용해서 '다시 던지기' 예시 재작성하기
프라미스 체이닝 챕터에서 다뤘던 ‘다시 던지기(rethrow)’ 관련 예시를 기억하실 겁니다. 이 예시를 .then/catch
대신 async/await
를 사용해 다시 작성해 봅시다.
그리고 demoGithubUser
안의 반복(recursion)은 반복문(loop)을 사용해 작성하도록 합시다. async/await
를 사용하면 쉽게 작성할 수 있습니다.
class HttpError extends Error {
constructor(response) {
super(`${response.status} for ${response.url}`);
this.name = 'HttpError';
this.response = response;
}
}
function loadJson(url) {
return fetch(url)
.then(response => {
if (response.status == 200) {
return response.json();
} else {
throw new HttpError(response);
}
})
}
// 유효한 사용자를 찾을 때까지 반복해서 username을 물어봄
function demoGithubUser() {
let name = prompt("GitHub username을 입력하세요.", "iliakan");
return loadJson(`https://api.github.com/users/${name}`)
.then(user => {
alert(`이름: ${user.name}.`);
return user;
})
.catch(err => {
if (err instanceof HttpError && err.response.status == 404) {
alert("일치하는 사용자가 없습니다. 다시 입력해 주세요.");
return demoGithubUser();
} else {
throw err;
}
});
}
demoGithubUser();
속임수랄게 없는 문제입니다. demoGithubUser
안의 .catch
를 try...catch
로 교체하고 필요한 곳에 async/await
를 추가하면 됩니다.
class HttpError extends Error {
constructor(response) {
super(`${response.status} for ${response.url}`);
this.name = 'HttpError';
this.response = response;
}
}
async function loadJson(url) {
let response = await fetch(url);
if (response.status == 200) {
return response.json();
} else {
throw new HttpError(response);
}
}
// 유효한 사용자를 찾을 때까지 반복해서 username을 물어봄
async function demoGithubUser() {
let user;
while(true) {
let name = prompt("GitHub username을 입력하세요.", "iliakan");
try {
user = await loadJson(`https://api.github.com/users/${name}`);
break; // 에러가 없으므로 반복문을 빠져나옵니다.
} catch(err) {
if (err instanceof HttpError && err.response.status == 404) {
// 얼럿 창이 뜬 이후에 반복문은 계속 돕니다.
alert("일치하는 사용자가 없습니다. 다시 입력해 주세요.");
} else {
// 알 수 없는 에러는 다시 던져집니다.
throw err;
}
}
}
alert(`이름: ${user.name}.`);
return user;
}
demoGithubUser();