Select
یک عملیات انتخابی منتظر میماند تا هر یک از مجموعهای از futureها آماده شود و به نتیجه آن future پاسخ میدهد. در JavaScript این مورد شبیه به Promise.race است و در پایتون با asyncio.wait(task_set, return_when=asyncio.FIRST_COMPLETED) قابل مقایسه میباشد.
مانند یک عبارت تطبیقی (match statement)، بدنه pattern دارای تعدادی بازو است که هر کدام به شکل عبارت pattern = future => statement هستند. هنگامی که future آماده است، مقدار بازگشتی آن توسط pattern تخریب میشود. سپس statement با متغیرهای حاصل اجرا میشود. در نتیجه statement نتیجهي ماکرو select! میشود.
use tokio::sync::mpsc;
use tokio::time::{sleep, Duration};
#[tokio::main]
async fn main() {
let (tx, mut rx) = mpsc::channel(32);
let listener = tokio::spawn(async move {
tokio::select! {
Some(msg) = rx.recv() => println!("got: {msg}"),
_ = sleep(Duration::from_millis(50)) => println!("timeout"),
};
});
sleep(Duration::from_millis(10)).await;
tx.send(String::from("سلام!")).await.expect("Failed to send greeting");
listener.await.expect("شنونده شکست خورد");
}
-
بلوک async
listenerدر اینجا یک شکل رایج است: منتظر برخی رویدادهای async یا بهعنوان مثال برای timeoutها باشید.sleepرا به sleep طولانیتر تغییر دهید تا شاهد شکست آن باشید. چراsendنیز در این شرایط شکست میخورد؟ -
select!is also often used in a loop in “actor” architectures, where a task reacts to events in a loop. That has some pitfalls, which will be discussed in the next segment.