前端数据字典的最优方案探索

3.2. 将后端传过来的key转成value显示(一般在表格中)。

现在来看第二种使用方式,这种方式一般在表格里面,当我获取表格数据的时候,假如里面有一项数据代表性别,后端给我的是一个 key 值,我在展示的时候需要将这个 key 转成 value。这个问题我最先想到的解决办法是vue的过滤器,但是过滤器又不能支持异步,如果非要使用过滤器的话(函数也一样),我必须在每次使用前先初始化字典数据,但是这样我就没法完全将字典相关代码从业务中脱离出来。(我花了很长时间寻找过滤器的异步方式,现在已经放弃了,根本没有。)

假如我使用一个组件。但是这样的话就和DictSelect一样了,假如表格页大小为10,那它就会同时发起10条相同的请求,这是真的接受不了。

3.3.逻辑判断

第三种情况,没有合适办法,只能在代码中写死。

四、解决方案


我封装了一个专门用来请求字典的函数, 他有两个逻辑:

每次发起请求时将当前请求的 Promise 存起来,请求结束后将Promise改为null,每次发起请求时先判断Promise是否存在,如果有就直接返回。这样可以处理那些同一时刻发起多个请求的问题。

发起请求之前先判断 Loca Storage 中是否有缓存,如果有直接取出来,没有的话再发起请求,成功之后会先缓存一份。


/**

 * 对get请求进行包装

 * 提供数据缓存和防止同时发起相同的请求

 * 相同的路径就可以理解为相同的请求

 */

import request from "@/utils//axios";



const promiseRecord = {}; // 用于缓存请求状态



/**

 * 通过路径和参数生成唯一字符

 * @param {*} apiUrl

 */

const createKey = (apiUrl) => {

  return apiUrl;

};



// 普通的 get 请求

const get = (apiUrl) => request.get(apiUrl)



/**

 * 用来发起需要缓存的请求

 * @param {String} apiUrl

 * @param {Boolean} refresh 可能在某些情况下不能使用缓存必须到后台获取

 */

const getCache = (apiUrl, refresh = false) => {

  // 用请求路径和参数生成标识,完全相同的请求的标识一样,作为储存的键

  let keyName = createKey(apiUrl);



  return new Promise((resolve, reject) => {

    let data = sessionStorage.getItem(keyName);



    let request = () => {

      get(apiUrl)

        .then((value) => {

          sessionStorage.setItem(keyName, JSON.stringify(value));

          resolve(value);

        })

        .catch((error) => {

          reject(error);

        });

    };



    if (data && !refresh) {

      // 如果用户手动修改了 sessionStorage 里的数据可能会出错,应该做下处理

      try {

        resolve(JSON.parse(data));

      } catch (e) {

        request();

      }

    } else {

      request();

    }

  });

};



/**

 * 防止重复处理

 */

const repeat = (apiUrl, request, refresh) => {

  // 用请求路径和参数生成标识,完全相同的请求的标识一样,可以使用同一个请求结果

  let keyName = createKey(apiUrl);



  if (!promiseRecord[keyName]) {

    promiseRecord[keyName] = new Promise((resolve, reject) => {

      request(apiUrl, refresh)

        .then((value) => {

          promiseRecord[keyName] = null;

          resolve(value);

        })

        .catch((error) => {

          promiseRecord[keyName] = null;

          reject(error);

        });

    });

  }



  return promiseRecord[keyName];

};



/**

 * 返回请求的函数

 * @param {String} apiUrl

 * @param {Object} options 配置项

 */

const getAxios = (apiUrl, options = {}) => {

  // 默认配置

  let defaults = {

    cache: false, // 是否开启缓存

    repeat: false, // 是否开启防止同时发起相同的请求

    refresh: false, // 是否刷新(这里也不能保证会刷新,因为get也有缓存,只能保证它会发出请求)

  };

  let _options = Object.assign(Object.assign({}, defaults), options);



  // 什么都不需要 返回原始的axiso get请求

  if (!_options.cache && !_options.repeat) {

    return get(apiUrl);

  }



  // 只需要缓存

  if (_options.cache && !_options.repeat) {

    return getCache(apiUrl, _options.refresh);

  }



  // 只需要防止同时发起相同的请求

  if (!_options.cache && _options.repeat) {

    return repeat(apiUrl, get);

  }




### 最后

![前15.PNG](https://img-blog.csdnimg.cn/img_convert/2b7847b6b8a0c5d63632bb2525c4688c.webp?x-oss-process=image/format,png)

![前16.PNG](https://img-blog.csdnimg.cn/img_convert/ab64f3e42255f1ddf1450b8bad390d1c.webp?x-oss-process=image/format,png)

>由于文档内容过多,为了避免影响到大家的阅读体验,在此只以截图展示部分内容
>





  // 只需要防止同时发起相同的请求

  if (!_options.cache && _options.repeat) {

    return repeat(apiUrl, get);

  }




### 最后

[外链图片转存中...(img-rxkTHlEq-1718090635332)]

[外链图片转存中...(img-sUtpIJ8h-1718090635333)]

>由于文档内容过多,为了避免影响到大家的阅读体验,在此只以截图展示部分内容
>


  • 10
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值