Vue2全局getSites函数遇请求锁时返回undefined问题求助
全局异步请求重复控制失效问题解决
问题场景
在Vue项目中,全局异步函数getSites用于从API获取站点列表,通过$store.state.lockSitesLoading变量防止重复请求:
- 当
lockSitesLoading为true时,期望监听该变量直到变为false,再递归调用getSites获取数据 - 当前实现中,进入监听分支后函数直接返回
undefined,导致await vm.getSites()无法拿到有效数据
现有代码
component.vue
async mounted() { let vm = this; const sites = await vm.getSites(); vm.sites = sites.data },
main.js
async getSites() { let vm = this; if (vm.$store.state.lockSitesLoading) { vm.$watch('$store.state.lockSitesLoading', () => vm.getSites()); } else { return vm._getSitesOnline(); // 实际发起API请求的函数 } }
问题根源
进入lockSitesLoading为true的分支时,getSites函数没有返回任何Promise,直接执行$watch后结束,导致await拿到的是undefined。$watch仅注册监听回调,不会阻塞函数或返回异步结果。
解决思路与修改代码
核心是在lock为true时返回一个Promise,等待lock变为false后再递归获取数据并resolve结果,同时清理监听避免内存泄漏:
修改main.js中的getSites函数:
async getSites() { let vm = this; // 如果正在加载,返回Promise等待lock释放 if (vm.$store.state.lockSitesLoading) { return new Promise((resolve) => { // 注册监听,lock变为false时触发 const unwatch = vm.$watch('$store.state.lockSitesLoading', (newVal) => { if (!newVal) { // 取消监听,避免内存泄漏 unwatch(); // 递归调用getSites,拿到结果后resolve resolve(vm.getSites()); } }); }); } else { // 正常发起请求 return vm._getSitesOnline(); } }
补充说明
- 用
Promise包裹监听逻辑,确保函数无论哪个分支都返回Promise,符合async函数规范 - 监听回调中判断
newVal为false时,立即取消监听(unwatch()),避免后续不必要的触发 - 递归调用
getSites后,将结果通过resolve返回,外层的await就能拿到正确的API数据
内容的提问来源于stack exchange,提问作者Paolo Dell'Orti
相关产品推荐
相关产品推荐

