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.