mirror of
https://github.com/rust-lang/rustlings.git
synced 2025-12-28 06:49:19 +00:00
add exercises of async
This commit is contained in:
parent
ac9443f516
commit
f7f2527951
@ -8,12 +8,6 @@ Discover the basics of asynchronous programming by writing your first async func
|
||||
## Using Async and Await
|
||||
Convert a traditional synchronous function to use async/await syntax. This exercise helps illustrate the benefits and usage of Rust’s async constructs.
|
||||
|
||||
## Understanding Task Execution
|
||||
Learn about executing multiple tasks concurrently without blocking. This exercise focuses on how Rust handles async task execution under the hood.
|
||||
|
||||
## Shared State in Async Code
|
||||
Tackle the challenges of managing shared state in an asynchronous context. Use synchronization tools like Mutexes to safely manage state across concurrent tasks.
|
||||
|
||||
## Error Handling in Async
|
||||
Navigate the complexities of error handling in async code. Understand how errors propagate differently in async workflows and how to handle them effectively.
|
||||
|
||||
|
||||
41
exercises/24_async/async1.rs
Normal file
41
exercises/24_async/async1.rs
Normal file
@ -0,0 +1,41 @@
|
||||
// This program creates multiple asynchronous tasks that each simulate a long-running operation
|
||||
// using `async` and `await`. Each task will return how much time it took to complete.
|
||||
// The program should wait until all the tasks have finished and should collect their return values into a vector.
|
||||
|
||||
use std::time::{Duration, Instant};
|
||||
use futures::executor::block_on; // For simplicity in an educational context, to block on async code
|
||||
|
||||
async fn perform_task(id: usize) -> u128 {
|
||||
let start = Instant::now();
|
||||
// Simulate async work using sleep
|
||||
tokio::time::sleep(Duration::from_millis(250)).await;
|
||||
println!("Task {id} done");
|
||||
start.elapsed().as_millis()
|
||||
}
|
||||
|
||||
async fn main_async() {
|
||||
let mut handles = Vec::new();
|
||||
for i in 0..10 {
|
||||
let handle = perform_task(i);
|
||||
handles.push(handle);
|
||||
}
|
||||
|
||||
let mut results = Vec::new();
|
||||
for handle in handles {
|
||||
// TODO: Use `.await` to collect the results of all tasks into the `results` vector.
|
||||
// Remember to handle each async task using the appropriate syntax for awaiting.
|
||||
}
|
||||
|
||||
if results.len() != 10 {
|
||||
panic!("Oh no! Some task isn't done yet!");
|
||||
}
|
||||
|
||||
println!();
|
||||
for (i, result) in results.into_iter().enumerate() {
|
||||
println!("Task {i} took {result}ms");
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
block_on(main_async());
|
||||
}
|
||||
31
exercises/24_async/async2.rs
Normal file
31
exercises/24_async/async2.rs
Normal file
@ -0,0 +1,31 @@
|
||||
// This program demonstrates the transformation of a synchronous function into an asynchronous one.
|
||||
// The original function performs a time-consuming operation, which we'll simulate with a sleep.
|
||||
// You need to convert this function to use async/await syntax and understand how it improves the responsiveness of the application.
|
||||
|
||||
use std::time::Duration;
|
||||
use futures::executor::block_on; // This is for running the async main function in this educational context.
|
||||
|
||||
// Synchronous version of a function that simulates a long-running operation
|
||||
fn calculate_value_synchronously() -> i32 {
|
||||
println!("Starting synchronous calculation...");
|
||||
std::thread::sleep(Duration::from_secs(2)); // Simulating a long-running task
|
||||
println!("Synchronous calculation done.");
|
||||
42 // returns a computed value
|
||||
}
|
||||
|
||||
// TODO: Convert this function to async version
|
||||
async fn calculate_value_asynchronously() -> i32 {
|
||||
|
||||
}
|
||||
|
||||
async fn main_async() {
|
||||
println!("Calling synchronous function:");
|
||||
let sync_result = calculate_value_synchronously();
|
||||
println!("Result from synchronous function: {}", sync_result);
|
||||
|
||||
// TODO: Call the async function here and print its result
|
||||
}
|
||||
|
||||
fn main() {
|
||||
block_on(main_async());
|
||||
}
|
||||
40
exercises/24_async/async3.rs
Normal file
40
exercises/24_async/async3.rs
Normal file
@ -0,0 +1,40 @@
|
||||
// This program demonstrates error handling in asynchronous Rust code. We will simulate a function that can fail,
|
||||
// and you will handle the error appropriately in an asynchronous context.
|
||||
|
||||
use std::time::Duration;
|
||||
use futures::executor::block_on; // For running the async main function in this educational context.
|
||||
use tokio; // We use tokio for the async functionality.
|
||||
use anyhow::{Result, anyhow}; // To simplify error handling
|
||||
|
||||
// Asynchronous function that might fail
|
||||
async fn might_fail(id: u32) -> Result<u32> {
|
||||
if id % 2 == 0 {
|
||||
tokio::time::sleep(Duration::from_millis(500)).await;
|
||||
Ok(id)
|
||||
} else {
|
||||
tokio::time::sleep(Duration::from_millis(500)).await;
|
||||
Err(anyhow!("Failed on odd id"))
|
||||
}
|
||||
}
|
||||
|
||||
async fn main_async() {
|
||||
let ids = [1, 2, 3, 4, 5];
|
||||
let mut results = Vec::new();
|
||||
|
||||
for id in ids {
|
||||
// TODO: Handle the potential error here using appropriate async error handling methods.
|
||||
// Consider using match or Result combinators like `map_err` or `and_then`.
|
||||
}
|
||||
|
||||
// Display results
|
||||
for result in results {
|
||||
match result {
|
||||
Ok(num) => println!("Processed number: {}", num),
|
||||
Err(e) => println!("Error occurred: {}", e),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
block_on(main_async());
|
||||
}
|
||||
41
solutions/24_async/async1.rs
Normal file
41
solutions/24_async/async1.rs
Normal file
@ -0,0 +1,41 @@
|
||||
// This program creates multiple asynchronous tasks that each simulate a long-running operation
|
||||
// using `async` and `await`, and each task will return how much time it took to complete.
|
||||
// The program should wait until all the tasks have finished and should collect their return values into a vector.
|
||||
|
||||
use std::time::{Duration, Instant};
|
||||
use futures::executor::block_on; // This will allow us to block on async code for simplicity in an educational context
|
||||
|
||||
async fn perform_task(id: usize) -> u128 {
|
||||
let start = Instant::now();
|
||||
// Simulate async work using sleep
|
||||
tokio::time::sleep(Duration::from_millis(250)).await;
|
||||
println!("Task {id} done");
|
||||
start.elapsed().as_millis()
|
||||
}
|
||||
|
||||
async fn main_async() {
|
||||
let mut handles = Vec::new();
|
||||
for i in 0..10 {
|
||||
let handle = perform_task(i);
|
||||
handles.push(handle);
|
||||
}
|
||||
|
||||
let mut results = Vec::new();
|
||||
for handle in handles {
|
||||
// Use `.await` to collect the results of all tasks into the `results` vector.
|
||||
results.push(handle.await);
|
||||
}
|
||||
|
||||
if results.len() != 10 {
|
||||
panic!("Oh no! Some task isn't done yet!");
|
||||
}
|
||||
|
||||
println!();
|
||||
for (i, result) in results.into_iter().enumerate() {
|
||||
println!("Task {i} took {result}ms");
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
block_on(main_async());
|
||||
}
|
||||
37
solutions/24_async/async2.rs
Normal file
37
solutions/24_async/async2.rs
Normal file
@ -0,0 +1,37 @@
|
||||
// This program demonstrates the transformation of a synchronous function into an asynchronous one.
|
||||
// The original function performs a time-consuming operation, which we'll simulate with a sleep.
|
||||
// You need to convert this function to use async/await syntax and understand how it improves the responsiveness of the application.
|
||||
|
||||
use std::time::Duration;
|
||||
use futures::executor::block_on; // This is for running the async main function in this educational context.
|
||||
use tokio; // We use tokio for the async sleep functionality.
|
||||
|
||||
// Synchronous version of a function that simulates a long-running operation
|
||||
fn calculate_value_synchronously() -> i32 {
|
||||
println!("Starting synchronous calculation...");
|
||||
std::thread::sleep(Duration::from_secs(2)); // Simulating a long-running task
|
||||
println!("Synchronous calculation done.");
|
||||
42 // returns a computed value
|
||||
}
|
||||
|
||||
// Converted to async version
|
||||
async fn calculate_value_asynchronously() -> i32 {
|
||||
println!("Starting asynchronous calculation...");
|
||||
tokio::time::sleep(Duration::from_secs(2)).await; // Using Tokio's async sleep
|
||||
println!("Asynchronous calculation done.");
|
||||
42 // returns a computed value
|
||||
}
|
||||
|
||||
async fn main_async() {
|
||||
println!("Calling synchronous function:");
|
||||
let sync_result = calculate_value_synchronously();
|
||||
println!("Result from synchronous function: {}", sync_result);
|
||||
|
||||
println!("Calling asynchronous function:");
|
||||
let async_result = calculate_value_asynchronously().await;
|
||||
println!("Result from asynchronous function: {}", async_result);
|
||||
}
|
||||
|
||||
fn main() {
|
||||
block_on(main_async());
|
||||
}
|
||||
43
solutions/24_async/async3.rs
Normal file
43
solutions/24_async/async3.rs
Normal file
@ -0,0 +1,43 @@
|
||||
// This program demonstrates error handling in asynchronous Rust code. We simulate a function that can fail,
|
||||
// and handle the error appropriately in an asynchronous context.
|
||||
|
||||
use std::time::Duration;
|
||||
use futures::executor::block_on; // For running the async main function in this educational context.
|
||||
use tokio; // We use tokio for the async functionality.
|
||||
use anyhow::{Result, anyhow}; // To simplify error handling
|
||||
|
||||
// Asynchronous function that might fail
|
||||
async fn might_fail(id: u32) -> Result<u32> {
|
||||
if id % 2 == 0 {
|
||||
tokio::time::sleep(Duration::from_millis(500)).await;
|
||||
Ok(id)
|
||||
} else {
|
||||
tokio::time::sleep(Duration::from_millis(500)).await;
|
||||
Err(anyhow!("Failed on odd id"))
|
||||
}
|
||||
}
|
||||
|
||||
async fn main_async() {
|
||||
let ids = [1, 2, 3, 4, 5];
|
||||
let mut results = Vec::new();
|
||||
|
||||
for id in ids {
|
||||
let result = might_fail(id).await;
|
||||
match result {
|
||||
Ok(num) => results.push(Ok(num)),
|
||||
Err(e) => results.push(Err(e)),
|
||||
}
|
||||
}
|
||||
|
||||
// Display results
|
||||
for result in results {
|
||||
match result {
|
||||
Ok(num) => println!("Processed number: {}", num),
|
||||
Err(e) => println!("Error occurred: {}", e),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
block_on(main_async());
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user