首页 > 解决方案 > 在 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
    }
}

标签: vue.js

解决方案


突变需要同步运行

做你的异步工作而不是突变

不是最好的实现,但您会从下面的代码中了解如何处理它。

//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)
    }

推荐阅读