Typescript 小工具 ---- 事件锁类(升级版)

Class

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
/**
 * @author ydq
 * @date 2019/05/28
 * @description 公共事件锁
 */
class _Locker {
  private _locker: any = {};

  /**
   * 设置存储位置
   * @param place
   * "session" sessionStorage
   * "local" localStorage
   * "memory" 内存中 (页面的刷新可能会导致锁数据丢失)
   */
  setSP(place: "session" | "local" | "memory" = "memory") {
    if (place == "session") this._locker = window.sessionStorage;
    if (place == "local") this._locker = window.localStorage;
  }

  clear(): void {
    this._locker = {};
  }

  // 获取锁状态
  get(key: string): boolean {
    const _key: string = `Locker_key_${key}`;
    return this._locker[_key];
  }
  // 
  lock(key: string): boolean {
    const _key: string = `Locker_key_${key}`;
    this._locker[_key] = true;
    return true;
  }
  // 解锁
  unlock(key: string): boolean {
    const _key: string = `Locker_key_${key}`;
    this._locker[_key] = false;
    return false;
  }

  /**
   * 可以自动解锁的 
   * 获取 key锁 的状态
   * 如果 没有锁 则上锁,并在 500 毫秒后自动解锁
   * 如果 在锁 则返回上锁状态
   * @param {*} key
   * @param {*} time
   */
  autoLocker(key: string, time = 500): boolean {
    const _now: number = Date.now();

    const _key: string = `Locker_key_${key}`;

    // 时间阀值越界处理
    this.resetAutoLocker(_now, _key, time);

    const isLock: boolean = _now < (this._locker[_key] || 0);
    if (isLock == false) {
      this._locker[_key] = _now + time;
      return false;
    }

    return isLock;
  }

  /**
   * 因为与客户端时间相关,所以需要一个阀值范围判断
   * @param now 当前时间
   * @param key key
   * @param time 阀值范围
   */
  private resetAutoLocker(now: number, key: string, time: number) {
    const _t1 = this._locker[key];
    if (!_t1) return;

    if (Math.abs(now - _t1) > time) {
      // 当前时间  存储时间差 > 阀值范围
      this._locker[key] = now;
    }
  }
}

const mLocker = new _Locker();
// 设置数据保存的位置
mLocker.setSP("session");
export default mLocker;

使用实例

import Locker from './Locker';

1
2
3
4
ClickAgain() {
    // 2s 内不会多次触发事件
    if (Locker.autoLocker('event:locker:ClickPlayAgain', 2000)) return;
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
Unlock(){
    Locker.get("key") // 返回 false

    Locker.lock("key") // 加锁

    Locker.get("key") // 返回 true

    Locker.unlock("key") // 解锁

    Locker.get("key") // 返回 false
}

作用

  1. 事件的防抖动处理
  2. 事件调用频率限制