【发布时间】:2020-04-26 04:27:06
【问题描述】:
我有一些组件可以单独或在同一页面上。这些组件中的每一个都使用相同的 Vuex 状态。由于它们都可以在其他页面上使用并且仍然可以工作,因此它们中的每一个都向同一个 Vuex action 发送调用,而后者又调用使用 axios 的服务 获取 JSON 数据。
所有这些都很棒!
但是,当我在一个页面上确实有 2 个(或更多)这些组件时,axios 调用会为每个组件调用 1 次。最初,我尝试查看数据是否存在并创建了一个“最后获取数据的时间”时间戳,这样我就可以绕过第二次调用。但是,这些都发生在组件 created 事件上,并且基本上是同时被调用的。
所以,输入debounce。这似乎是确切的原因。但是,当我实现它时,它失败并传递到下一行代码而不是awaiting。我做错了什么?
议程组件(使用相同状态的组件)
async created() {
await this.gatherCalendarData();
},
methods: {
async gatherCalendarData() {
await this.$store.dispatch('time/dateSelected', this.$store.state.time.selectedDate);
},
},
月份组件(另一个,注意它们是相同的)
async created() {
await this.gatherCalendarData();
},
methods: {
async gatherCalendarData() {
await this.$store.dispatch('time/dateSelected', this.$store.state.time.selectedDate);
},
},
动作被调用
async dateSelected(context, data) {
let result = await getCalendarData(isBetween.date, context.rootState.userId);
await context.commit('SET_MONTHLY_DATA', { result: result.Result, basedOn: isBetween.date });
},
这个getCalendarData 方法位于我创建的用于进行 api 调用的服务文件中(如下)
这是我收到的调用此操作的错误(每个组件一次)。
[Vue warn]: Error in created hook (Promise/async): "TypeError: Cannot read property 'Result' of undefined"
指的是上面的第 3 行:result: result.Result
API 服务
const getCalendarData = debounce(async (givenDate, userId) => {
let response = await getCalendarDataDebounced(givenDate, userId);
return response;
}, 100);
const getCalendarDataDebounced = async (givenDate, userId) => {
let result = await axiosGet('/api/v2/ProjectTime/BuildAndFillCalendarSQL', {
givenDate: givenDate,
userID: userId,
});
return result;
};
Axios 包装器
const axiosGet = async (fullUrl, params) => {
let result = null;
try {
let response = await axios.get(fullUrl, params ? { params: params } : null);
result = await response.data;
} catch(error) {
console.error('error:', error);
}
return result;
};
如果我在 getCalendarData 调用之前、之后和内部以及 getCaledarDataDebounced 方法中放置 console.log 消息:(假设页面上只有 2 个组件)日志显示之前的 2,然后显示之后的 2日志出现。接下来是上面提到的 2 个组件中的每一个的错误,然后记录一个“getCalendarData 内部”,最后记录来自实际获取数据的去抖动版本中的日志。
因此,似乎去抖功能正在发挥作用,因为它只运行了一次。但似乎await call let result = await getCalendarData(isBetween.date, context.rootState.userId); 并不是真正的Waiting。
我错过了什么吗?
回答后编辑
根据@JakeHamTexas 的回答,我现在的dateSelected 中的action 是(实际的完整代码,没有像上面那样删除,以免混淆任何东西):
async dateSelected(context, data) {
console.log('dateSelected action');
let isBetween = isDateWithinCurrentMonth(data, context.state);
if (!isBetween.result) {
// The date selected is in a different month, so grab that months data
return new Promise(resolve => {
getCalendarData(isBetween.date, context.rootState.userId)
.then(result => {
console.log('inside promise');
context.commit('SET_MONTHLY_DATA', { result: result.Result, basedOn: isBetween.date });
context.commit('SET_SELECTED_DATE', isBetween.date);
context.commit('statistics/TIME_ENTRIES_ALTERED', true, { root: true });
resolve();
});
});
} else {
// The date selected is within the given month, so simply select it
context.commit('SET_SELECTED_DATE', data);
}
context.commit('CLEAR_SELECTED_TIME_ENTRY_ID');
},
我对@987654341@ 的 API 调用现在是:
const getCalendarData = async (givenDate, userId) => {
console.log('getting calendar data');
let result = await axiosGet('/api/v2/ProjectTime/BuildAndFillCalendarSQL', {
givenDate: givenDate,
userID: userId,
});
return result;
};
错误消失了!但是,它似乎不是 debouncing - 这意味着所有内容都被调用了 3 次。我希望 dateSelected action 被调用 3 次。但我想避免 getting calendar data 被调用 3 次。如果有帮助,这就是控制台的样子:
dateSelected action
getting calendar data
dateSelected action
getting calendar data
dateSelected action
getting calendar data
inside promise
inside promise
inside promise
【问题讨论】: