class AsyncValue(Generic[T]):
值包装器,提供等待值或过渡的能力。
概要:
>>> a = AsyncValue(0) # 注意:可以包装任何类型(枚举,元组,...)
>>> ...
>>> a.value = 5 # 访问底层值
>>> ...
>>> # 等待值通过等式匹配
>>> await a.wait_value(7)
>>> ...
>>> # 通过谓词等待值匹配
>>> await a.wait_value(lambda v: v > 10)
>>> ...
>>> # 通过迭代获取值(具有最终一致性)
>>> async for value in a.eventual_values(lambda v: v > 10):
>>> ...
>>> # 等待任何过渡
>>> await a.wait_transition()
>>> ...
>>> # 通过等式等待过渡
>>> await a.wait_transition(14)
>>> ...
>>> # 通过谓词等待过渡
>>> await a.wait_transition(lambda v, old: v > 10 and old < 0)
>>> ...
>>> # 通过迭代获取重复的过渡(在阻塞时错过值)
>>> async for value, _ in a.transitions(lambda v, old: v > 10 and old < 0):
>>> ...
在使用此API中的任何等待方法或迭代器时,请注意,在调用者接收控制权之前,该值可能已经再次发生了变化。为了清晰,总是返回触发唤醒的特定值。
比较eventual_values()和transitions()迭代器:
eventual_values() transitions()
================= =============
• 高级别 & 安全 • 低级别 & 需要小心
• 每次值变化和开始循环时进行评估 • 如果调用者在主体中未被阻塞,则每次值变化时进行评估
• 最终迭代最新值 • 如果调用者被阻塞,可能会错过最新值
• 可能会错过快速的值变化 • 可能会错过快速的值变化
• 条件只使用新值 • 条件使用新值和/或旧值
• 主要用于同步状态 • 主要用于触发工作
• 不受用户竞争影响 • 初始化和每次迭代可能存在竞争
(尤其是在值变化不频繁的情况下)
性能注意:赋值给value属性通常具有O(N)的复杂性,其中N是主动等待的任务的数量。可能的话,共享的谓词会被分组,将N减少到活动谓词的数量。