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();