为何使用await获取axios Promise返回数据时始终得到Promise对象
问题根源
所有被async关键字标记的函数,无论内部返回什么值,调用后都会固定返回一个Promise实例,你直接用const data = getToken()的写法,拿到的永远是Promise对象,不可能同步拿到内部包裹的业务数据,这是JavaScript异步机制的固定规则,和axios本身无关。
另外你尝试的链式调用写法存在低级拼写错误:.then被你写成了.tnen,该回调根本不会被执行,自然拿不到返回值。
正确取值方式
Promise的内部结果只能通过两种方式获取,不存在同步直接取值的方案:
方式1:在async函数内使用await等待结果
非ES模块环境下不支持顶层裸写await,需要把调用逻辑包裹在async函数中执行:
const loadLoginData = async () => { try { // await等待Promise resolve,拿到axios响应对象 const response = await getToken(); // axios返回的业务数据统一存放在响应对象的data字段下 const businessData = response.data; console.log('接口返回数据:', businessData); // 所有依赖接口返回值的后续逻辑,都需要写在await之后的当前函数内 } catch (err) { // 手动捕获请求/代码报错 console.error('登录请求失败:', err); } } // 执行函数 loadLoginData();
如果你的运行环境支持ES模块顶层await(比如现代浏览器原生模块、Node.js ESM环境),也可以直接在顶层写:
const response = await getToken(); const businessData = response.data;
方式2:使用.then链式回调获取结果
注意拼写正确,不要和await混用导致重复等待:
getToken() .then(response => { const businessData = response.data; console.log('接口返回数据:', businessData); // 依赖返回值的逻辑写在then回调内部 }) .catch(err => { console.error('登录请求失败:', err); })
代码优化建议
- 你已经给axios实例配置了
baseURL: "http://localhost:8080",后续发请求不需要写全路径,直接传接口路径即可,比如instance.post("/login", userData),避免重复拼接url引发异常。 - 403拦截器里更新token的逻辑有问题:你只修改了全局axios的默认请求头,没有更新自己创建的
instance实例的请求头,会导致重试请求依然不带新token,建议修改为:
instance.interceptors.response.use((response) => { return response }, async function (error) { const originalRequest = error.config; if (error.response.status === 403 && !originalRequest._retry) { originalRequest._retry = true; const access_token = await refreshAccessToken(); // 更新当前实例的默认头,同时给当前重试请求单独加头 instance.defaults.headers.common['Authorization'] = 'Bearer ' + access_token; originalRequest.headers['Authorization'] = 'Bearer ' + access_token; return instance(originalRequest); } return Promise.reject(error); });
- 你代码中多处把
response拼写为responce,虽然不影响运行,但建议统一修正,避免后续维护时出现变量名不匹配的问题。 - 你在
getToken里给post请求单独加的Content-Type: application/json头是多余的,创建实例的时候已经全局配置过该头,不需要重复传。
内容的提问来源于stack exchange,提问作者Omegon
相关产品推荐
相关产品推荐

