• Vue公共loading升级版(处理并发异步差时响应)


    公共loading是项目系统中很常见的场景,处理方式也不外乎三个步骤:

    1. 通过全局状态管理定义状态值(vuex、pinia等)。

    1. 在程序主入口监听状态值变化,从而展示/隐藏laoding动画。

    1. 在请求和相应拦截器中变更状态值。

    第一二步骤处理大同小异,但在第三步中,网上很多博文分享的方法是:在请求拦截中展示loading,在响应拦截器中判断收到成功响应时直接隐藏loading,这种方法看似可行但实际过程中却有问题。

    例如,假设在第0秒时同时向后台发送了两个异步请求A和B,由于网络或处理逻辑不同,A请求0.5秒秒收到成功响应,B请求2秒才收到。那在第0.5秒,响应拦截器就会把loading状态变更,结束loading动画,但此时B请求还没收到返回。如果用户接下来的操作同时需要A和B请求的数据,提前结束动画会让用户体检变差。

    解决思路:定义一个全局对象来存储每个接口的响应状态,直到每个请求接口都收到响应才变更状态,结束loading动画。因为键名的唯一性,可以使用接口路径(或唯一接口编号)作为键名。请求时添加一个键值对,响应时变更键值,同时遍历对象状态值进行判断

    1. let apiStatusList ={
    2. '/api/a':true,//true请求中
    3. '/api/b':false //false请求完成
    4. }

    具体操作如下(以vue3的pinia为例):

    定义一个loading.js

    1. import { defineStore } from 'pinia';
    2. export const useLoadStore = defineStore('storeLoading', {
    3. state: () => {
    4. return {
    5. apiStatusList:{},
    6. loading:false, //网络加载状态,true加载中
    7. };
    8. },
    9. actions: {
    10. updateLoadingState(value){
    11. this.loading = value
    12. },
    13. setApiStatusList(value){
    14. this.apiList = value;
    15. }
    16. }
    17. });

    拦截器处理:

    1. import axios from 'axios';
    2. import { useLoadStore } from '../stores/loading';
    3. const request = axios.create();
    4. //请求拦截
    5. request.interceptors.request.use(
    6. (config) => {
    7. //公共loading
    8. const loadStore = useLoadStore();
    9. let statusList = { ...loadStore.apiStatusList };
    10. statusList[config.url] = true; //接口赋值为请求中
    11. loadStore.setApiStatusList(statusList);
    12. if (!loadStore.loading) { //判断loading是否正在展示中
    13. loadStore.updateLoadingState(true);
    14. }
    15. return config;
    16. },
    17. (error) => {
    18. return Promise.reject(error);
    19. }
    20. )
    21. //响应拦截
    22. request.interceptors.response.use(
    23. (response) => {
    24. const loadStore = useLoadStore();
    25. let statusList = { ...loadStore.apiStatusList };
    26. statusList[response.config.url] = false; 接口赋值为请求完成
    27. if (!Object.values(statusList).includes(true)) { //遍历对象,判断接口是否全部返回
    28. if (loadStore.loading) {
    29. loadStore.updateLoadingState(false);
    30. loadStore.setApiStatusList({});
    31. }
    32. } else {
    33. loadStore.setApiStatusList(statusList);
    34. }
    35. },
    36. (error) => {//有接口报错,重置loading
    37. const loadStore = useLoadStore();
    38. if (loadStore.loading) {
    39. loadStore.updateLoadingState(false);
    40. loadStore.setApiStatusList({});
    41. }
    42. }

    App.vue监听状态变化

    1. //监听store状态值时需要传入function
    2. watch(()=>loadStore.loading,(newValue, oldValue)=>{
    3. if(newValue){
    4. showLoadingToast({
    5. duration: 0,
    6. forbidClick: true,
    7. });
    8. }else{
    9. closeToast();
    10. }
    11. })

    文章转载自:波特卡斯D

    原文链接:https://www.cnblogs.com/zyj-Blogs/p/17844283.html

  • 相关阅读:
    一个集成的BurpSuite漏洞探测插件1.1
    了解稀疏数组
    【数据挖掘】百度机器学习-数据挖掘-自然语言处理工程师 2023届校招笔试详解
    numpy生成数组
    Springboot 项目 org.apache.poi 版本冲突
    Springboot项目中@JsonProperty不生效-如何处理呢?
    在pytorch中使用Tensorboard
    10.26 知识总结(python操作MySQL、SQL注入问题、事务、触发器等)
    什么是FOF,什么是信托
    Java:关于Java和Python你应该知道的区别
  • 原文地址:https://blog.csdn.net/kfashfasf/article/details/134530247