回到课程

使用 async/await 重写 "rethrow"

下面你可以看到 “rethrow” 的例子。让我们来用 async/await 重写它,而不是使用 .then/catch

同时,我们可以在 demoGithubUser 中使用循环以摆脱递归:在 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); } }); } // 询问用户名,直到 github 返回一个合法的用户 function demoGithubUser() { let name = prompt("Enter a name?", "iliakan"); return loadJson(`https://api.github.com/users/${name}`) .then(user => { alert(`Full name: ${user.name}.`); return user; }) .catch(err => { if (err instanceof HttpError && err.response.status == 404) { alert("No such user, please reenter."); 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); } } // 询问用户名,直到 github 返回一个合法的用户 async function demoGithubUser() { let user; while(true) { let name = prompt("Enter a name?", "iliakan"); try { user = await loadJson(`https://api.github.com/users/${name}`); break; // 没有 error,退出循环 } catch(err) { if (err instanceof HttpError && err.response.status == 404) { // 循环将在 alert 后继续 alert("No such user, please reenter."); } else { // 未知的 error,再次抛出(rethrow) throw err; } } } alert(`Full name: ${user.name}.`); return user; } demoGithubUser();