0

我的 Vue 应用程序使用 Vuex 商店。有时用户可以“重置”会话。这需要将 vuex 存储重置为默认值,因此任何挂起的异步操作都应该被删除,因为 Vuex 存储已被重置。问题是当异步调用返回时,它们会尝试修改存储,但它已被重置。当用户点击“重置”时,如何强制忽略任何挂起的异步操作。

我想回顾一下“createStore”Vuex 函数,但这会导致死胡同,因为全局存储变量已更新。

编辑:我最终传递了一个带有每个突变的 StoreID。我将这个 StoreID 值存储在所有异步操作开头的变量中。突变验证何时调用商店当前处于相同的 StoreID 版本。有没有更聪明的方法来做到这一点?

4

2 回答 2

0

案例 1. 您正在使用 fetch:

const controller = new AbortController();
const {
  signal
} = controller;

actions: {
  fetchSoemthing(context, { url, options }) {
    fetch(url, {
      ...options,
      signal, //<------ This is our AbortSignal
    }).then(response => {
      console.log(`Request 1 is complete!`);
    }).catch(e => {
      console.warn(`Fetch 1 error: ${e.message}`);
    });
  },
  cancelAllRequests(context) {
    return controller.abort(); // in your usecase when you call the resetStoreData, you also dispatch this action.
  }
}

我不是 100% 确定信号是如何工作的,但我最好的建议是让您使用包装类进行 fetch 不要像这样直接在商店中使用它,而是在您当前的实现中尝试一下,看看它是如何工作的去。

案例2,您正在使用axios:

import axios from "axios";

const { CancelToken } = axios;
const cancelToken = CancelToken.source();

actions: {
  fetchSoemthing(context, {
    url,
    options
  }) {
    axios.post(url, options, {
        cancelToken,
      })
      .then((response) => {
        //responce Body
      })
      .catch((error) => {
        if (axios.isCancel(error)) {
          console.log("post Request canceled");
        }
      });
  },
  cancelAllRequests(context) {
    return cancelToken.cancel(); // in your usecase when you call the resetStoreData, you also dispatch this action.
  }
}

对于这两种实现,如果您想同时取消它们,您必须对每个请求使用相同的 canceltoken / 信号,因此我建议您在外部文件或 Vuex 状态中声明它。

于 2021-05-21T12:28:45.930 回答
0

在解决/拒绝请求承诺之前,您可以将 StoreID 检查移至请求层。如果自发出请求后 StoreID 已更改,则通过不调用 resolve 或拒绝来忽略结果。这将允许您从商店的其余部分中删除支票,因为在您更新 StoreID 之前发送的请求永远不会调用突变。

如果您使用 axios 或具有取消请求能力的其他选项,则另一种选择是将所有挂起的请求取消令牌保存在一个数组中,并在您重置商店时将它们全部取消。这里的一个问题是,如果您的请求被拒绝的原因是因为它被取消,您将需要检查您的请求错误处理。

axios.isCancel(err); // will be true if request was canceled
于 2021-05-19T15:02:37.820 回答