pub struct Receiver<T> { /* private fields */ }展开描述
实现§
Source§impl<T> Receiver<T>
impl<T> Receiver<T>
Sourcepub fn borrow(&self) -> Ref<'_, T>
pub fn borrow(&self) -> Ref<'_, T>
返回对最近发送的值的引用。
此方法不会将返回的值标记为已读,因此即使您已经通过调用 borrow 看到该值,后续对 changed 的调用也可能立即返回。
未完成的 borrow 持有内部值的读锁。这意味着长期存活的 borrow 可能导致生产者半部阻塞。建议尽可能缩短 borrow 的生命周期。此外,如果您运行在允许 !Send future 的环境中,必须确保返回的 Ref 类型不会跨 .await 点存活,否则可能导致死锁。
锁的优先级策略依赖于底层锁实现,此类型不保证会使用任何特定策略。特别是,等待在 send 中获取锁的生产者可能会也可能不会阻塞对 borrow 的并发调用,例如:
Potential deadlock example
// Task 1 (on thread A) | // Task 2 (on thread B)
let _ref1 = rx.borrow(); |
| // will block
| let _ = tx.send(());
// may deadlock |
let _ref2 = rx.borrow(); |有关何时使用此方法与 borrow_and_update 的更多信息,请参见此处。
§示例
use tokio::sync::watch;
let (_, rx) = watch::channel("hello");
assert_eq!(*rx.borrow(), "hello");Sourcepub fn borrow_and_update(&mut self) -> Ref<'_, T>
pub fn borrow_and_update(&mut self) -> Ref<'_, T>
返回对最近发送的值的引用,并将该值标记为已读。
此方法将当前值标记为已读。在 Sender 再次修改共享值之前,后续对 changed 的调用不会立即返回。
未完成的 borrow 持有内部值的读锁。这意味着长期存活的 borrow 可能导致生产者半部阻塞。建议尽可能缩短 borrow 的生命周期。此外,如果您运行在允许 !Send future 的环境中,必须确保返回的 Ref 类型不会跨 .await 点存活,否则可能导致死锁。
锁的优先级策略依赖于底层锁实现,此类型不保证会使用任何特定策略。特别是,等待在 send 中获取锁的生产者可能会也可能不会阻塞对 borrow 的并发调用,例如:
Potential deadlock example
// Task 1 (on thread A) | // Task 2 (on thread B)
let _ref1 = rx1.borrow_and_update(); |
| // will block
| let _ = tx.send(());
// may deadlock |
let _ref2 = rx2.borrow_and_update(); |有关何时使用此方法与 borrow 的更多信息,请参见此处。
Sourcepub fn has_changed(&self) -> Result<bool, RecvError>
pub fn has_changed(&self) -> Result<bool, RecvError>
检查此通道是否包含此接收者尚未看到的消息。当前值不会标记为已读。
尽管此方法名为 has_changed,它并不检查消息是否相等,因此即使当前消息等于前一个消息,此调用也会返回 true。
§Errors
当且仅当通道已关闭时返回 RecvError。
§示例
§Basic usage
use tokio::sync::watch;
let (tx, mut rx) = watch::channel("hello");
tx.send("goodbye").unwrap();
assert!(rx.has_changed().unwrap());
assert_eq!(*rx.borrow_and_update(), "goodbye");
// The value has been marked as seen
assert!(!rx.has_changed().unwrap());§Closed channel example
use tokio::sync::watch;
let (tx, rx) = watch::channel("hello");
tx.send("goodbye").unwrap();
drop(tx);
// The channel is closed
assert!(rx.has_changed().is_err());Sourcepub fn mark_changed(&mut self)
pub fn mark_changed(&mut self)
将状态标记为已更改。
调用此方法后,无论是否已发送新值,has_changed() 都返回 true 并且 changed() 立即返回。
这对于在订阅后触发初始更改通知以同步新接收者很有用。
Sourcepub fn mark_unchanged(&mut self)
pub fn mark_unchanged(&mut self)
将状态标记为未更改。
当前值将被接收者视为已读。
如果您对接收者中可见的当前值不感兴趣,这很有用。
Sourcepub async fn changed(&mut self) -> Result<(), RecvError>
pub async fn changed(&mut self) -> Result<(), RecvError>
等待更改通知,然后将当前值标记为已读。
如果调用此方法时通道中的当前值尚未被标记为已读,则该方法会将该值标记为已读并立即返回。如果最新值已被标记为已读,则该方法将休眠,直到与此 Receiver 连接的 Sender 发送新消息或所有 Sender 都被丢弃。
For more information, see 变更通知 in the module-level documentation.
§Errors
如果通道已关闭且当前值已被视为已读,则返回 RecvError。
§Cancel safety
此方法是取消安全的。如果您在 tokio::select! 语句中将其作为事件使用,并且其他分支首先完成,则可以保证本次 changed 调用没有将任何值标记为已读。
§示例
use tokio::sync::watch;
let (tx, mut rx) = watch::channel("hello");
tokio::spawn(async move {
tx.send("goodbye").unwrap();
});
assert!(rx.changed().await.is_ok());
assert_eq!(*rx.borrow_and_update(), "goodbye");
// The `tx` handle has been dropped
assert!(rx.changed().await.is_err());Sourcepub async fn wait_for(
&mut self,
f: impl FnMut(&T) -> bool,
) -> Result<Ref<'_, T>, RecvError>
pub async fn wait_for( &mut self, f: impl FnMut(&T) -> bool, ) -> Result<Ref<'_, T>, RecvError>
等待满足所提供条件的值。
每當通道上发送内容时,此方法都会调用所提供闭包。一旦闭包返回 true,此方法将返回传递给闭包的值的引用。
在 wait_for 开始等待更改之前,它会针对当前值调用闭包。如果给定当前值时闭包返回 true,则 wait_for 将立即返回对当前值的引用。即使当前值已被视为已读也是如此。
watch 通道仅跟踪最近的值,因此如果发送多条消息的速度快于 wait_for 调用闭包的速度,则它可能会跳过某些更新。每当闭包被调用时,都会以最近的值调用它。
当此函数返回时,当闭包返回 true 时传递给闭包的值将被视为已读。
如果通道已关闭,wait_for 将返回 RecvError。一旦发生这种情况,就再也不会在通道上发送任何消息。返回错误时,保证已对最后一个值调用过闭包,并且它对该值返回了 false。(如果闭包返回了 true,那么将返回最后一个值而不是错误。)
与 borrow 方法一样,返回的 borrow 持有内部值的读锁。这意味着长期存活的 borrow 可能导致生产者半部阻塞。建议尽可能缩短 borrow 的生命周期。有关更多信息,请参阅 borrow 的文档。
§Cancel safety
此方法是取消安全的。如果您在 tokio::select! 语句中将其作为事件使用,并且其他分支首先完成,则可以保证最后看到的值 val(如果有)满足 f(val) == false。
§Panics
当且仅当闭包 f panic 时。在这种情况下,此 Receiver 拥有或共享的任何资源都不会被毒化。
§示例
use tokio::sync::watch;
use tokio::time::{sleep, Duration};
#[tokio::main(flavor = "current_thread", start_paused = true)]
async fn main() {
let (tx, mut rx) = watch::channel("hello");
tokio::spawn(async move {
sleep(Duration::from_secs(1)).await;
tx.send("goodbye").unwrap();
});
assert!(rx.wait_for(|val| *val == "goodbye").await.is_ok());
assert_eq!(*rx.borrow(), "goodbye");
}Sourcepub fn same_channel(&self, other: &Self) -> bool
pub fn same_channel(&self, other: &Self) -> bool
如果接收者属于同一通道则返回 true。
§示例
let (tx, rx) = tokio::sync::watch::channel(true);
let rx2 = rx.clone();
assert!(rx.same_channel(&rx2));
let (tx3, rx3) = tokio::sync::watch::channel(true);
assert!(!rx3.same_channel(&rx2));