为什么我的函数未等待API请求响应就执行后续操作?
问题根因
- 异步执行时序问题:
axios.post返回的是Promise异步对象,调用login方法后不会阻塞后续代码执行,请求未完成时_instance还是初始化的空对象,此时调用isInstanceWorking自然拿到空值,第二次调用时请求已经完成,所以能拿到正常实例。 - 代码语法错误:你提供的Vue组件代码中,
mounted钩子结束后未添加逗号,会触发语法报错,干扰逻辑执行。 - 缺少状态判断:没有对登录请求的执行状态做标记,无法提前判断实例是否完成初始化。
修复方案
1. 修正Vue组件异步逻辑
新增登录状态标记,用async/await规范异步调用,代码如下:
import Api from "../api.js" export default{ name : "login", data : () => ({ API: null, isLoginLoading: false, // 登录请求状态标记,防止未完成请求时调用后续方法 games: [] // 后续存储游戏数据的字段 }), mounted() { this.API = new Api(); }, // 补全缺失的逗号 methods : { // 改成async异步方法 async login(){ this.isLoginLoading = true try { // await等待登录请求完成再往下执行 const response = await this.API.login("username", "password") this.API.createInstance(response.data.token) // 此处后续的操作都能保证实例已经初始化完成 this.isInstanceWorking() // 可以直接调用后续扩展的接口 this.games = await this.API.getGames() } catch (error) { // 可自定义登录失败的提示逻辑 console.error('登录失败:', error) } finally { this.isLoginLoading = false } }, isInstanceWorking(){ // 提前判断请求状态和实例状态 if (this.isLoginLoading) { console.log('登录请求进行中,请稍后再试') return } if (!this.API?._instance) { console.log('请先完成登录再执行该操作') return } console.log(this.API.instance) } } }
2. 扩展API类适配后续需求
你后续要新增的接口方法可以直接封装在API类内部,统一用内部的实例发起请求,避免外层重复判断实例状态,优化后代码如下:
export default class API { constructor() { this._instance = null; // 无需登录的公共请求用默认实例 this._publicInstance = axios.create({ baseURL: "thisisanexample.com", timeout: 1000, }); } get instance() { // 优先返回登录后的鉴权实例,兜底返回公共实例 return this._instance || this._publicInstance; } set instance(newInstance) { this._instance = newInstance; } login(username, password) { return this._publicInstance.post("/login", { username, password, }); } createInstance(token) { this._instance = axios.create({ baseURL: "thisisanexample.com", timeout: 1000, headers: { Authorization: "Bearer " + token }, }); } // 后续新增的游戏接口直接封装在类内部 async getGames() { const res = await this.instance.get('/games') return res.data } }
核心逻辑说明
所有依赖登录鉴权状态的操作,都必须放在登录请求的异步回调(then回调或者await关键字之后)执行,就能完全避免时序不同步的问题。
内容的提问来源于stack exchange,提问作者JohnW2Smith
相关产品推荐
相关产品推荐

