TLDR: 当函数有时返回Promise有时抛出异常时,它很难使用。编写异步函数时,更喜欢通过返回被拒绝的Promise来表示失败
您的特定示例混淆了它们之间的一些重要区别:
因为您在Promise链中进行错误处理,所以抛出的异常会自动转换为被拒绝的Promise。这可以解释为什么它们似乎可以互换——它们不是。
考虑以下情况:
checkCredentials = () => {
let idToken = localStorage.getItem('some token');
if ( idToken ) {
return fetch(`https://someValidateEndpoint`, {
headers: {
Authorization: `Bearer ${idToken}`
}
})
} else {
throw new Error('No Token Found In Local Storage')
}
}
这将是一种反模式,因为您将需要同时支持异步和同步错误情况。它可能看起来像:
try {
function onFulfilled() { ... do the rest of your logic }
function onRejected() { // handle async failure - like network timeout }
checkCredentials(x).then(onFulfilled, onRejected);
} catch (e) {
// Error('No Token Found In Local Storage')
// handle synchronous failure
}
不好,这正是Promise.reject
(在全局范围内可用)可以解决问题并有效地将其与throw
. 重构现在变成:
checkCredentials = () => {
let idToken = localStorage.getItem('some_token');
if (!idToken) {
return Promise.reject('No Token Found In Local Storage')
}
return fetch(`https://someValidateEndpoint`, {
headers: {
Authorization: `Bearer ${idToken}`
}
})
}
这现在允许您仅使用一个catch()
来处理网络故障和缺少令牌的同步错误检查:
checkCredentials()
.catch((error) => if ( error == 'No Token' ) {
// do no token modal
} else if ( error === 400 ) {
// do not authorized modal. etc.
}