vue.js - 在 Vuex Store 中正确使用 setInterval
问题描述
我当前的解决方案有效:我从 API 获取数据。但是 Vue 不喜欢它。
setInterval
在不“在突变处理程序之外改变 vuex 存储状态”的情况下,在 Vuex 存储中使用的正确方法是什么?
在Index.vue
:
mounted () {
store.dispatch('setAPIEndpoint', {
endpoint: 'chillersystem',
requestType: 'post',
payload: {},
})
},
在actions.js
:
async setAPIEndpoint ({ commit }, payload) {
commit('SET_API_ENDPOINT', payload)
}
在mutations.js
:
SET_API_ENDPOINT (state, payload) {
// Clear the previous interval to prevent a memory leak
if (state.api.interval !== null) {
state.api.interval = null
state.api.data = {}
}
// Reset the API parameters
state.api.endpoint = payload.endpoint
state.api.requestType = payload.requestType
state.api.payload = payload.payload
// Schedule repetition
state.api.interval = setInterval(() => {
if (state.api.requestType === 'post') {
axios.post(`/api/${ state.api.endpoint }`, state.api.payload)
.then((response) => {
state.api.data = response.data
})
.catch((error) => {
process.env.NODE_ENV === 'production' ? location.href = 'pages/error-500/' : console.log(error)
})
}
}, state.api.refreshTimer)
}
在state.js
const state = {
api: {
endpoint: '',
requestType: '',
payload: {},
data: {},
refreshTimer: 5000, // Milli-seconds
interval: null
}
}
解决方案
突变需要同步运行
做你的异步工作而不是突变
不是最好的实现,但您会从下面的代码中了解如何处理它。
//mutations.js
SET_API_ENDPOINT(state, payload) {
// Clear the previous interval to prevent a memory leak
if (state.api.interval !== null) {
state.api.interval = null
state.api.data = {}
}
// Reset the API parameters
state.api.endpoint = payload.endpoint
state.api.requestType = payload.requestType
state.api.payload = payload.payload
state.api.interval = payload.interval
state.api.data = payload.data
}
//actions.js:
async setAPIEndpoint({ commit, state }, payload) {
const endpoint = payload.endpoint;
const requestType = payload.requestType;
const payload = payload.payload;
let data = null;
let interval = null;
const getData = () => {
return new Promise((resolve, reject) => {
interval = setInterval(() => {
if (requestType === 'post') {
axios.post(`/api/${endpoint}`, payload)
.then((response) => {
data = response.data;
resolve();
})
.catch((error) => {
process.env.NODE_ENV === 'production' ? location.href = 'pages/error-500/' : console.log(error)
reject();
})
}
}
, state.api.refreshTimer);
})
};
await getData();
const newPayload = {
...payload,
data,
interval
}
commit('SET_API_ENDPOINT', newPayload)
}
推荐阅读
- android - 为什么我的 Toast.makeText 不显示任何内容
- woocommerce - Woocommerce webhook 不会为非管理员用户触发
- sql - 基于特定记录集的 Oracle 循环序列
- html - CSS : 只有一个 div 可滚动
- java - 如何使用 Apache Common CSV CSVPrinter 添加新行?
- java - NServiceBus 和 Java 集成
- c# - Xamarin Form - 如何在 UWP 中以 PDF 或 JPEG 格式存储图像
- javascript - 如何声明一个 PHP 变量并将其传递给 AJAX url?
- python - 如何解决模块未找到错误cython
- php - Excel - 从相应数据中获取第 2 个或第 n 个匹配字符串