26个版本

0.8.8 2024年6月22日
0.8.7 2023年9月19日
0.8.6 2023年8月3日
0.8.5 2023年7月20日
0.5.0 2023年3月29日

#44 in 异步

Download history 1237/week @ 2024-05-04 1396/week @ 2024-05-11 1406/week @ 2024-05-18 1326/week @ 2024-05-25 1404/week @ 2024-06-01 1358/week @ 2024-06-08 1437/week @ 2024-06-15 2000/week @ 2024-06-22 1921/week @ 2024-06-29 1496/week @ 2024-07-06 1663/week @ 2024-07-13 1797/week @ 2024-07-20 1379/week @ 2024-07-27 1174/week @ 2024-08-03 810/week @ 2024-08-10 1125/week @ 2024-08-17

4,765 每月下载
用于 13 个crate (5个直接使用)

MPL-2.0 许可证

65KB
886

眼球

此crate实现了一种基本的观察者模式,适用于Rust。它提供了一个类型 Observable<T>,它半透明地包装一个内部值 T 并向任何关联的 Subscriber<T> 通知变化。目前,Subscriber 只能通过 async / .await 进行轮询以获取更新,但这可能在将来发生变化。

还有一个 SharedObservable<T> 作为另一种变体,它实现了 Clone 但没有 Deref。它比在 Arc<RwLock<_>> 中放置 Observable 更易于使用且更高效,可以从代码中的多个地方更新值。

以下是一个快速概述

use eyeball::Observable;

let mut observable = Observable::new("A".to_owned());
// Observable has no methods of its own, as those could conflict
// with methods of the inner type, which it `Deref`erences to.
let mut subscriber1 = Observable::subscribe(&observable);
let mut subscriber2 = Observable::subscribe(&observable);

// You can get the current value from a subscriber without waiting
// for updates.
assert_eq!(subscriber1.get(), "A");

Observable::set(&mut observable, "B".to_owned());
// `.next().await` will wait for the next update, then return the
// new value.
assert_eq!(subscriber1.next().await, Some("B".to_owned()));

// If multiple updates have happened without the subscriber being
// polled, the next poll will skip all but the latest.
Observable::set(&mut observable, "C".to_owned());
assert_eq!(subscriber1.next().await, Some("C".to_owned()));
assert_eq!(subscriber2.next().await, Some("C".to_owned()));

// You can even obtain the value without cloning the value, by
// using `.read()` (no waiting) or `.next_ref().await` (waits for
// the next update).
// If you restrict yourself to these methods, you can even use
// `Observable` with inner types that don't implement the `Clone`
// trait.
// However, note that while a read guard returned by `.read()` or
// `.next_ref().await` is alive, updating the observable is
// blocked.
Observable::set(&mut observable, "D".to_owned());
{
    let guard = subscriber1.next_ref().await.unwrap();
    assert_eq!(*guard, "D");
}

// The latest value is kept alive by subscribers when the
// `Observable` is dropped.
drop(observable);
assert_eq!(subscriber1.get(), "D");
assert_eq!(*subscriber2.read(), "D");

此库目前针对低(0 - 4)数量的订阅者进行了优化。如果您关心几十个订阅者的性能,或者正在使用数百个订阅者,请提出问题以进行讨论。

有关更多详细信息,请参阅 docs.rs 上的文档

依赖项

~0–11MB
~110K SLoC