如何在其他函数中使用axios异步请求返回的access_token值
核心结论
不能直接把then回调中的console.log替换为return来获取可全局同步使用的token字符串。async定义的异步函数永远返回Promise对象,网络请求的结果不会同步返回,如果你在then回调里return值,这个值只会被包装成新的Promise返回,外层同步代码永远无法第一时间拿到值,比如下面的写法是完全无效的:
// 错误示例:同步代码拿不到异步返回的token let globalToken; getAccessToken().then(res => { globalToken = res.access_token; }); console.log(globalToken); // 永远输出undefined,因为这行执行时token请求还没完成
所有依赖token的逻辑,都必须放在Promise的决议流程(await后或者then回调内)执行。
正确使用方式
方式1:async/await写法(推荐,可读性最高)
只要在需要使用token的函数前加上async关键字,就可以通过await直接拿到resolve后的token字符串,和写同步代码的逻辑一致:
// 示例:调用需要携带token的业务接口 const getBusinessList = async () => { // 等待token请求完成,直接拿到返回结果 const tokenRes = await getAccessToken(); const accessToken = tokenRes.access_token; // 后续逻辑可以直接使用accessToken字符串 const { data } = await axios.get(`${baseUrl}/api/business/list`, { headers: { Authorization: `Bearer ${accessToken}` } }); return data; }; // 调用async函数时,同样需要处理返回的Promise getBusinessList().then(list => { console.log('业务列表:', list); }).catch(err => { console.error('请求失败:', err); });
方式2:then链式调用写法
如果项目环境不支持async/await,可以把所有依赖token的逻辑放在then的回调函数中,通过链式调用传递结果:
getAccessToken() .then(res => { const accessToken = res.access_token; // 所有需要用到accessToken的逻辑都写在当前回调内 return axios.get(`${baseUrl}/api/business/list`, { headers: { Authorization: `Bearer ${accessToken}` } }); }) .then(listRes => { console.log('业务列表:', listRes.data); }) .catch(err => { console.error('请求链路出错:', err); });
代码优化建议
- 修复现有代码的请求头错误:你当前配置里的
Content_Type写法有误,应该为Content-Type(中间是短横线而非下划线),否则部分服务端无法识别表单请求格式。 - 增加token缓存逻辑,避免每次调用接口都重复请求授权接口,减少不必要的网络开销:
// 缓存token和过期时间 let cachedToken = null; let tokenExpireTimestamp = 0; const getAccessToken = async () => { const currentTime = Date.now(); // 如果缓存的token距离过期还有1分钟以上,直接返回缓存值 if (cachedToken && currentTime < tokenExpireTimestamp) { return { access_token: cachedToken }; } try { const body = new URLSearchParams({ grant_type: 'client_credentials', scope: 'manage:all' }).toString(); const config = { headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, auth: { username: clientId, password: clientSecret } }; const { data: res } = await axios.post( `${baseUrl}/oauth2/token`, body, config ); // 更新缓存,预留60秒缓冲时间避免临界点token失效 cachedToken = res.access_token; tokenExpireTimestamp = currentTime + (res.expires_in - 60) * 1000; return res; } catch (err) { // 不要吞掉错误,抛出后交由调用方统一处理 throw err; } };
内容的提问来源于stack exchange,提问作者psych0groov3
相关产品推荐
相关产品推荐

