You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

当前同步调用函数,如何实现异步函数并行调用并返回全部结果与错误?

实现F#异步函数的并行调用并收集所有结果与错误

要实现异步函数的并行调用,同时保留每个调用的成功结果或错误信息,F#里可以借助Async.Parallel结合Result类型轻松搞定——毕竟你已经在requestAsync里用Result封装了结果和错误,这一步刚好能用上。

完整示例代码

首先补全必要的类型定义(假设你还没定义Error类型),再实现并行调用的逻辑:

// 定义错误类型
type Error = {
    code: int
    message: string
}

let requestAsync (url: string) : Async<Result<string, Error>> = async { 
    Console.WriteLine ("Simulating request " + url) 
    try 
        do! Async.Sleep(1000) 
        // 模拟部分请求失败,比如URL包含"2"的返回错误
        if url.Contains("2") then
            return Error {code = 500; message = "Internal Server Error";}
        else
            return Ok (url + ": body...") 
    with :? WebException as e -> 
        return Error {code = 500; message = "Internal Server Error";} 
}

[<TestMethod>]
member this.TestParallelAsyncCalls() =
    // 准备要调用的URL列表
    let targetUrls = [
        "https://api.example.com/resource1"
        "https://api.example.com/resource2"
        "https://api.example.com/resource3"
    ]

    // 把每个URL转换成对应的异步任务
    let asyncTasks = targetUrls |> List.map requestAsync

    // 并行执行所有异步任务,可指定最大并行度(可选)
    // 比如限制最多同时跑2个请求:Async.Parallel 2 asyncTasks
    let parallelTask = Async.Parallel asyncTasks

    // 测试方法里同步等待所有任务完成(实际异步场景用do!替代)
    let allResults = Async.RunSynchronously(parallelTask)

    // 遍历处理所有结果
    allResults |> Array.iter (function
        | Ok successBody -> 
            Console.WriteLine($"✅ 请求成功: {successBody}")
        | Error errorDetails -> 
            Console.WriteLine($"❌ 请求失败 [Code: {errorDetails.code}]: {errorDetails.message}")
    )

关键逻辑说明

  • 并行执行核心:Async.Parallel会将一组异步任务转换成一个异步任务,它会并行启动所有子任务,而非串行执行。和循环串行调用相比,所有请求会同时启动(受限于指定的并行度),总耗时接近单个请求的时间(而非N倍)。
  • 保留所有结果:因为每个requestAsync已经通过Result类型封装了成功/失败状态,Async.Parallel不会因某个子任务失败而终止整个并行任务——每个子任务的错误都会被妥善封装到Error里,最终你会得到包含所有结果的数组。
  • 并行度控制:如果担心同时发起太多请求导致资源耗尽,可以用Async.Parallel的重载版本,传入整数指定最大并行数(比如Async.Parallel 3 asyncTasks表示最多同时跑3个请求)。

注意事项

在非测试场景(比如ASP.NET Core应用)里,尽量避免用Async.RunSynchronously,而是用do!或者Async.AwaitTask来异步等待并行任务完成,避免阻塞线程。

内容的提问来源于stack exchange,提问作者Developer11

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 04:24:32