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