File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change 1+ import asyncio
2+ from time import time
3+
4+
5+ class Setter :
6+ def __init__ (self , initial_value = None ) -> None :
7+ self ._value = initial_value
8+
9+ def get (self ):
10+ return self ._value
11+
12+ def set (self , v ):
13+ self ._value = v
14+
15+
16+ def debounce (delay ):
17+ """
18+ Debounce decorator.
19+
20+ @see Python 中的防抖与节流 https://www.bilibili.com/read/cv13257868
21+ """
22+
23+ # 用于存储 asyncio.Task 实例,这里是闭包
24+ task = Setter ()
25+
26+ def decorator (fn ):
27+ # Task 协程函数
28+ async def f (* args , ** kwargs ):
29+ # 进行休眠
30+ await asyncio .sleep (delay )
31+ # 调用函数
32+ f1 = fn (* args , ** kwargs )
33+ # 支持回调函数是异步函数的情况
34+ if asyncio .iscoroutine (f1 ):
35+ await f1
36+ # 清除 task
37+ task .set (None )
38+
39+ def wrapper (* args , ** kwargs ):
40+ # 如果 task 存在,说明在 delay 秒内调用过一次函数,此次调用应当重置计时器,因此取消先前的 Task
41+ if task .get () is not None :
42+ task .get ().cancel ()
43+ # 创建 Task 并赋值变量 task
44+ task .set (asyncio .create_task (f (* args , ** kwargs )))
45+
46+ return wrapper
47+
48+ return decorator
49+
50+
51+ def throttle (delay ):
52+ """
53+ Throttle decorator.
54+
55+ @see Python 中的防抖与节流 https://www.moyu.moe/articles/25/
56+ """
57+
58+ # 下一次许可调用的时间,初始化为 0
59+ next_t = Setter (0 )
60+
61+ def decorator (fn ):
62+ def wrapper (* args , ** kwargs ):
63+ # 当前时间
64+ now = time ()
65+ # 若未到下一次许可调用的时间,直接返回
66+ if next_t .get () > now :
67+ return
68+ # 更新下一次许可调用的时间
69+ next_t .set (now + delay )
70+ # 调用函数并返回
71+ return fn (* args , ** kwargs )
72+
73+ return wrapper
74+
75+ return decorator
You can’t perform that action at this time.
0 commit comments