为何无法从Vuex中被防抖函数包裹的方法获取返回值
问题原因与解决方案
问题原因分析
防抖函数未返回Promise
原action是async函数,本身会返回Promise,但你的防抖函数返回的是普通函数,内部通过setTimeout执行原函数时,并没有把原函数的Promise传递出来。调用防抖后的getPosts时,得到的是undefined而非Promise,因此.then里的data自然为undefined。参数引用错误
- action中调用
debounce时第三个参数写的是id,这个变量未定义,会直接抛出错误; - 防抖函数里取
args[1].params[id],但你调用getPosts时传入的是{id: this.getUUID()},并没有params属性,导致uniqueId为undefined,防抖逻辑完全失效。
- axios参数传递错误
你直接把payload作为axios.get的第二个参数,但axios的get请求参数需要放在config.params中,否则参数不会正确拼接到URL上。
修正方案
1. 修复防抖函数,使其返回Promise
修改防抖函数,让返回的函数始终返回Promise,同时处理重复调用时的Promise状态:
export function debounce(fn, wait = 1000, idKey) { const timers = {}; const pendingPromises = {}; return function(...args) { // 获取唯一标识,对应payload中的指定字段 const uniqueId = args[1][idKey]; if (!uniqueId) { // 无唯一标识时直接执行原函数 return fn.apply(this, args); } // 清除已有定时器 if (timers[uniqueId]) { clearTimeout(timers[uniqueId]); } // 返回已存在的pending Promise,避免重复创建 if (pendingPromises[uniqueId]) { return pendingPromises[uniqueId]; } const promise = new Promise((resolve, reject) => { timers[uniqueId] = setTimeout(async () => { try { const result = await fn.apply(this, args); resolve(result); } catch (err) { reject(err); } finally { // 执行完成后清理资源 delete timers[uniqueId]; delete pendingPromises[uniqueId]; } }, wait); }); pendingPromises[uniqueId] = promise; return promise; }; }
2. 修正action.js中的调用
将debounce的第三个参数改为具体的字段名(比如你传入的id),同时修正axios的参数传递:
import { debounce } from '../../Utils' export default { getPosts : debounce(async function(context, payload = {}) { // axios get请求参数需放在params中 const resp = await axios.get(`https://jsonplaceholder.typicode.com/posts`, { params: payload }); if (resp.status === 200) { return resp.data; } else { throw new Error(`Error statusText-->${resp.statusText}`); } }, 500, 'id') }
3. 修正组件中的调用方式
按照Vuex规范调用action,同时用await或.then处理返回值:
methods: { async fetchPosts() { try { const data = await this.$store.dispatch('getPosts', { id: this.getUUID() }); console.log('posts..........', data); } catch (err) { console.error(err); } } }
内容的提问来源于stack exchange,提问作者EaBengaluru
相关产品推荐
相关产品推荐

