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

Swift中如何使用异步函数的完成处理程序版本?

问题

我有一个异步函数func doWork(id: String) async throws -> String,想从并发调度队列中调用它做测试,原本想这么写:

for i in 1...100 {
    queue.async {
        obj.doWork(id: "foo") { result, error in 
          // 处理结果
        }
    }
}

这么写是因为queue.async { try await obj.doWork() }不被支持,会报错误:

Cannot pass function of type '@Sendable () async throws -> Void' to parameter expecting synchronous function type

但编译器并没有为doWork(id:)生成带完成处理程序的版本,不过在Objective-C里我可以用这个版本:[obj doWorkWithId: @"foo" completionHandler:^(NSString * val, NSError * _Nullable error) { ... }]。请问在Swift中怎么实现类似操作?


解决方法

1. 手动封装带完成回调的版本

给原异步函数写一个扩展,封装出适配GCD的带completionHandler的版本:

extension YourObjectType {
    func doWork(id: String, completionHandler: @escaping (String?, Error?) -> Void) {
        Task {
            do {
                let result = try await self.doWork(id: id)
                completionHandler(result, nil)
            } catch {
                completionHandler(nil, error)
            }
        }
    }
}

之后就可以按你最初的写法在GCD队列中调用:

for i in 1...100 {
    queue.async {
        obj.doWork(id: "foo") { result, error in
            if let error = error {
                // 处理错误逻辑
                print("执行失败:\(error)")
                return
            }
            if let result = result {
                // 处理结果逻辑
                print("执行结果:\(result)")
            }
        }
    }
}

2. 直接用Task适配GCD队列

如果不想额外封装,也可以在GCD的同步闭包内部启动Task来执行异步逻辑:

for i in 1...100 {
    queue.async {
        Task {
            do {
                let result = try await obj.doWork(id: "foo")
                // 处理结果
                print("执行结果:\(result)")
            } catch {
                // 处理错误
                print("执行失败:\(error)")
            }
        }
    }
}

这种方式里,GCD的async保证闭包在指定队列启动,内部的Task则负责处理异步逻辑的调度。

补充说明

GCD的async方法仅接受同步闭包,你最初传入的async throws异步闭包类型不匹配,因此编译器报错。上述两种方案都是将异步逻辑包装成GCD可接受的同步闭包形式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 23:55:24