use std::future::Future;
use tokio::task::JoinHandle;
// 定义一个函数类型别名,用于表示异步任务函数
type AsyncTask<Input, Output> =
Box<dyn FnOnce(Input) -> Pin<Box<dyn Future<Output = Result<Output, anyhow::Error>>>>;
// 高阶函数,按顺序执行异步任务
async fn execute_task_chain<T>(tasks: Vec<AsyncTask<T, T>>) -> Result<T, anyhow::Error> {
let mut result = tasks[0](Default::default()).await?;
for task in tasks.iter().skip(1) {
result = task(result).await?;
}
Ok(result)
}
// 示例异步任务函数
async fn task1(input: i32) -> Result<i32, anyhow::Error> {
Ok(input + 1)
}
async fn task2(input: i32) -> Result<String, anyhow::Error> {
Ok(format!("Result: {}", input))
}
async fn task3(input: String) -> Result<u32, anyhow::Error> {
Ok(input.len() as u32)
}
#[tokio::main]
async fn main() -> Result<(), anyhow::Error> {
let tasks: Vec<AsyncTask<_, _>> = vec![
Box::new(task1),
Box::new(task2),
Box::new(task3),
];
let final_result = execute_task_chain(tasks).await?;
println!("Final result: {}", final_result);
Ok(())
}
类型处理
- AsyncTask类型别名:定义了一个通用的异步任务函数类型,它接受一个输入类型
Input
,返回一个Future
,这个Future
的输出是一个Result
,包含输出类型Output
或anyhow::Error
。
- 高阶函数
execute_task_chain
:它接受一个Vec<AsyncTask<T, T>>
,表示一系列输入输出类型相同的异步任务。这确保了任务间参数传递的类型一致性。
错误处理
- Result类型:所有异步任务函数和
execute_task_chain
都返回Result
类型,其中Err
变体使用anyhow::Error
,这是一个方便的错误类型,可以包含任何类型的错误信息。
await
操作:在execute_task_chain
中,每次执行异步任务后使用?
操作符来处理可能的错误,如果任何一个任务出错,整个任务链将提前结束并返回错误。
异步操作逻辑
- 任务顺序执行:
execute_task_chain
函数中,首先执行第一个任务,并将其结果存储在result
中。然后通过for
循环依次执行后续任务,每次都将上一个任务的结果作为参数传递给下一个任务。
- Tokio运行时:通过
#[tokio::main]
宏,代码在Tokio运行时环境中执行,使得异步函数可以在这个环境中被调度和执行。