1,问题表现
一般在前端项目开发中,请求会统一处理:增加请求拦截器和响应拦截器。在响应拦截器中,可能会有如下逻辑:
以 axios
为例:
// 响应拦截器
axios.interceptors.response.use(
(response) => {
if (response.data.code === "000000") {
return Promise.resolve(response);
} else {
// 非 000000 也算错误
return Promise.reject(response);
}
},
// 状态码非 200
(error) => {
return Promise.reject(error);
}
);
在业务代码中,同事问我为啥没有跳转?下面是我模拟的代码逻辑:
const getInfo = () => {
// 模拟状态码 200,但 code !== 100013 的情况
return Promise.reject({ code: "100013", msg: "出错了" });
};
const handleClick = async () => {
try {
getInfo().then((data) => {
// 其他逻辑
console.log('data', data);
});
} catch (error) {
if (error.data.code === '100013') {
// 跳转逻辑
console.log('error', error);
}
}
};
handleClick();
2,原因分析
getInfo()
返回的是一个 rejected
状态的 Promise
对象,注意它是一个对象,并没有报错或是异常,所以不会走到 try...catch
中的 catch
中。另外:
- 有
then()
处理函数,但then()
不会执行; - 没有
catch()
处理函数,所以获取不到rejected
已决状态的结果。
3,解决
更改如下即可:
const handleClick = () => {
try {
getInfo()
.then((data) => {
// 其他逻辑
console.log("data", data);
})
.catch((error) => {
if (error.data.code === "100013") {
// 跳转
console.log("error", error);
}
});
} catch (error) {
// 其他执行错误
}
};
或使用 await
await
用于等待一个 Promise 对象已决后,获取已决后的结果,如果结果为rejected
状态,则抛出异常,可以用try...catch
捕获。Promise 参考
const handleClick = async () => {
try {
const data = await getInfo();
// 其他逻辑
console.log("data", data);
} catch (error) {
if (error.data.code === "100013") {
// 跳转
console.log("error", error);
}
}
};
3,其他相关
从 finally 语句块返回 会是什么情况?
如果从
finally
块中返回一个值,那么这个值将会成为整个try-catch-finally
的返回值,无论是否有return
语句在try
和catch
中。这包括在catch
块里抛出的异常。
注意下面的2段代码的执行结果:
(() => {
try {
try {
throw new Error("oops");
} catch (ex) {
console.error("inner", ex.message);
throw ex;
} finally {
console.log("finally");
}
} catch (ex) {
console.error("outer", ex.message);
}
})();
// inner oops
// finally
// outer oops
下面代码只是多了一个return
:
(() => {
try {
try {
throw new Error("oops");
} catch (ex) {
console.error("inner", ex.message);
throw ex;
} finally {
console.log("finally");
return;
}
} catch (ex) {
console.error("outer", ex.message);
}
})();
// inner oops
// finally
以上。