全局 loading

好久不见!

做项目中一直想用一个统一的 loading 状态控制全部的接口加载,但是一直不知道怎么处理,最近脑子突然灵光了一下想到了一个办法。

首先设置一个全局的 loading 状态,优先想到的就是 Pinia

然后因为页面会有很多接口会同时触发接口调用,但是接口响应时间是不一定的,所以采用计数法处理,代码如下

import { defineStore, acceptHMRUpdate } from "pinia";

export const useLoadingStore = defineStore({
  id: "loading",

  state: () => ({
    count: 0
  }),

  getters: {
    /**
     * 控制 loading 状态
     * 因为接口都是异步调用,所以想了一个办法,利用 Count 计数来控制 loading
     * 取消请求 -1
     * 添加请求 +1
     * 请求报错 -1
     * 请求成功 -1
     * 请求失败 -1
     * 基本可以保证最后一定是 0
     * @returns {boolean}
     */
    loading() {
      return this.count > 0;
    }
  },
  actions: {
    openLoading() {
      this.count + 1
    },
    closeLoading() {
      this.count - 1
    }
  }
});

// 确保传递正确的 store 声明,本例中为 `useLoadingStore`
if (import.meta.hot) {
  import.meta.hot.accept(acceptHMRUpdate(useLoadingStore, import.meta.hot));
}

估计大佬也看出来了,虽然是个方法,但是很不严谨。因为简单的计数法,会有出现负数的情况,甚至两个接口同时响应的情况(当然这种很极端)

我询问了后端大佬,给我提供了一种互斥锁的概念可以融入其中,所以出现了现在的最好版本

先设计一个互斥锁

let lock = false;

/**
 * 互斥锁 处理非常理超级极端的情况(忽略不计,顺便学习而已)
 * 开始锁
 * @returns {promise}
 */
export const acquireLock = () => {
  return new Promise(resolve => {
    if (!lock) {
      lock = true;
      resolve();
    } else {
      setTimeout(resolve, 0);
    }
  });
};

/**
 * 释放锁
 */
export const releaseLock = () => {
  lock = false;
};

然后引入锁,并且计算的时候,引入 Math.max 方法

import { defineStore, acceptHMRUpdate } from "pinia";
import { acquireLock, releaseLock } from "@/utils/lock.js";

export const useLoadingStore = defineStore({
  id: "loading",

  state: () => ({
    // loading: false
    count: 0
  }),

  getters: {
    /**
     * 控制 loading 状态
     * 因为接口都是异步调用,所以想了一个办法,利用 Count 计数来控制 loading
     * 取消请求 -1
     * 添加请求 +1
     * 请求报错 -1
     * 请求成功 -1
     * 请求失败 -1
     * 基本可以保证最后一定是 0
     * @returns {boolean}
     */
    loading() {
      return this.count > 0;
    }
  },
  actions: {
    async openLoading() {
      // this.loading = true;
      await acquireLock();
      try {
        this.count = Math.max(1, this.count + 1); // 确保count不会变成负数
      } finally {
        releaseLock();
      }
    },
    async closeLoading() {
      // this.loading = false;
      await acquireLock();
      try {
        this.count = Math.max(0, this.count - 1); // 确保count不会变成负数
      } finally {
        releaseLock();
      }
    }
  }
});

// 确保传递正确的 store 声明,本例中为 `useLoadingStore`
if (import.meta.hot) {
  import.meta.hot.accept(acceptHMRUpdate(useLoadingStore, import.meta.hot));
}

这样就可以

看下效果


count 为几就说明有几个接口还未响应

今天就这样,又是小白学习的一天,加油!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值