我如何在 for 循环中等待所有生成的 JoinHandles
How do I await all spawned JoinHandles in a for loop
我有以下代码:
#[tokio::main]
async fn main() {
let db: Db = Arc::new(Mutex::new(HashMap::new()));
let block_res = get_block_addresses().await;
match block_res {
Ok(v) => {
println!("Block downloaded, grabbing contracts");
println!("Txs: {}", v.result.transactions.len());
for obj in v.result.transactions {
let db1 = db.clone();
let db2 = db.clone();
let to = obj.to.clone();
let from = obj.from.clone();
tokio::spawn(async move {
let resp = check_if_contract(to, db1).await;
});
tokio::spawn(async move {
let resp = check_if_contract(from, db2).await;
});
}
}
Err(e) => {
println!("error parsing header: {:?}", e);
}
}
}
如您所见,它从不等待生成结果。在 for 循环完成后,我如何正确等待这些 JoinHandle
s?我想避免使用一系列任务并迭代它们。因为我在 Jon Gjengset 的视频中看到存在类似 NotifyHandle
的东西,它按 ID 存储任务。但我不知道如何使用它,或者它在这种情况下是否有意义。我是生锈和异步编程的新手,所以我希望我的问题有一定道理。
此时对于动态数量的任务,最有效的方法是利用 FuturesUnordered,它代表 Future
的集合,可以在其中等待下一个 [=11] =] 解决。
在你的情况下,它应该是:
let tasks = FuturesUnordered::new();
for obj in v.result.transactions {
let db1 = db.clone();
let db2 = db.clone();
let to = obj.to.clone();
let from = obj.from.clone();
tasks.push(tokio::spawn(async move {
check_if_contract(to, db1).await
}));
tasks.push(tokio::spawn(async move {
check_if_contract(from, db2).await
}));
}
while let Some(finished_task) = tasks.next().await {
match finished_task {
Err(e) => { /* e is a JoinError - the task has panicked */},
Ok(result) => { /* result is the result of check_if_contract */ }
}
}
如果您需要在最终循环中识别事务,return 从您生成的函数中识别任务的东西 - 那么它将成为 result
的一部分。
我有以下代码:
#[tokio::main]
async fn main() {
let db: Db = Arc::new(Mutex::new(HashMap::new()));
let block_res = get_block_addresses().await;
match block_res {
Ok(v) => {
println!("Block downloaded, grabbing contracts");
println!("Txs: {}", v.result.transactions.len());
for obj in v.result.transactions {
let db1 = db.clone();
let db2 = db.clone();
let to = obj.to.clone();
let from = obj.from.clone();
tokio::spawn(async move {
let resp = check_if_contract(to, db1).await;
});
tokio::spawn(async move {
let resp = check_if_contract(from, db2).await;
});
}
}
Err(e) => {
println!("error parsing header: {:?}", e);
}
}
}
如您所见,它从不等待生成结果。在 for 循环完成后,我如何正确等待这些 JoinHandle
s?我想避免使用一系列任务并迭代它们。因为我在 Jon Gjengset 的视频中看到存在类似 NotifyHandle
的东西,它按 ID 存储任务。但我不知道如何使用它,或者它在这种情况下是否有意义。我是生锈和异步编程的新手,所以我希望我的问题有一定道理。
此时对于动态数量的任务,最有效的方法是利用 FuturesUnordered,它代表 Future
的集合,可以在其中等待下一个 [=11] =] 解决。
在你的情况下,它应该是:
let tasks = FuturesUnordered::new();
for obj in v.result.transactions {
let db1 = db.clone();
let db2 = db.clone();
let to = obj.to.clone();
let from = obj.from.clone();
tasks.push(tokio::spawn(async move {
check_if_contract(to, db1).await
}));
tasks.push(tokio::spawn(async move {
check_if_contract(from, db2).await
}));
}
while let Some(finished_task) = tasks.next().await {
match finished_task {
Err(e) => { /* e is a JoinError - the task has panicked */},
Ok(result) => { /* result is the result of check_if_contract */ }
}
}
如果您需要在最终循环中识别事务,return 从您生成的函数中识别任务的东西 - 那么它将成为 result
的一部分。