vuex、pinia 同一时间多个组件请求同一个异步接口,是否能控制后续的请求直接获取第一个的结果?

如题,假如store中有一个专门获取数据的异步接口 test,但是有很多页面都会发送这个action,是否能控制后续请求从第一个接口中获取呢?
我用的Pinia,当然它应该和vuex比较像

阅读 2.8k
4 个回答

可以从 Promise 的特性下手。你可以把发起请求的 Promise 缓存下来,然后返回给所有发起请求的接口。这样,同时发起的请求,在结果返回前都进去等待状态;当结果返回后都会进入处理进程。

代码大概是这样:

import { fetchListFromApi } from './api';

export const useStore = defineStore(() => {
  let p;
  async function getList() {
    if (p) return p;

    p = fetchListFromApi();
    const list = await p;
    p = null;
    return list;
  }

  return {
    getList,
  };
});

比如说你有个全局的数据 menuList: [], 还有一个 menuListState: 0 0表示未初始化,1表示初始化进行中,2表示加载成功,3表示加载失败。

那么你在 action 就可以判断了

if(this.menuListState === 0 || this.menuListState === 4){
    this.menuListState = 1;
    fetch().then(()=>{
        this.menuListState = 2;
    }).catch(()=>{
        this.menuListState = 3;
    })
}

这样操作你就可以判断出来是否是加载中,当然你也可以把 fetch 存起来,以便于在其他结果中返回,也可以再增加过期时间这样的操作。

如果真的是多个组件需要共用一个接口的数据。你可以抽离出来。提升到上一层,来发送请求,然后在通过pinia来分发数据。不太建议在每个组件里面去执行同一个action

既然用到pinia在状态管理,就是为了解决多个组件共用数据的问题,所以你的设计可能存在一定的问题,为什么每个组件还在单独请求网络数据, 而不是用pinia的state.
如果真的有每个组件单独请求数据的需要,只能考虑缓存了,用Service Workers也是一种比较方便的解决方案

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题