У меня есть несколько компонентов, которые могут быть отдельными или на одной странице. Каждый из этих компонентов использует одно и то же состояние Vuex . Поскольку каждый из них может использоваться на других страницах и все еще работать, каждый из них отправляет вызов тому же Vuex действию , которое, в свою очередь, вызывает службу, которая использует ax ios для получения данных JSON.
Все это прекрасно работает!
Однако, когда у меня есть 2 (или более) этих компонентов на одной странице, это ax ios вызов вызывается 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;
};
Ax ios Wrapper
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;
};
Если я помещаю console.log
сообщения до, после и внутри вызова getCalendarData
, а также в методы getCaledarDataDebounced
: (при условии, что на страница) отображаются журналы 2 до и затем появляются журналы 2 после. Затем регистрируется ошибка, упомянутая выше для каждого из 2 компонентов, затем регистрируется одно «внутри getCalendarData
» и, наконец, журнал из дебазованной версии, куда он на самом деле получает данные.
Так что похоже Десиманс работает в том, что он запускается только один раз. Но похоже, что await
вызов let result = await getCalendarData(isBetween.date, context.rootState.userId);
не является действительно Ожиданием.
Я что-то здесь упускаю?
РЕДАКТИРУЕТСЯ после ответа
Основано на ответе @JakeHamTexas, мой action
из dateSelected
теперь (фактический полный код, ничего не удалено, как указано выше, чтобы ничего не путать):
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');
},
И мой вызов API getCalendarData
теперь:
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