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

Swift新Concurrency框架下实现「单次执行、等待全部完成」并发模式

问题分析

你要实现的是**「合并重复请求」**的并发模式:当异步任务正在执行时,后续请求不会重复触发任务,而是等待当前任务完成后统一获取结果。原DispatchQueue版本通过串行队列保护状态、存储回调数组,任务完成后批量执行回调;而你尝试的Actor版本,后续请求看到isRunning为true时直接返回,未等待任务完成,导致提前结束,不符合预期。

纯Swift Concurrency实现方案

我们可以在Actor中维护当前正在执行的任务引用,让后续请求直接await该任务,利用Swift异步机制自动处理结果传递,无需手动管理回调数组:

actor NewTest {
    private var currentTask: Task<Void, Error>?
    
    func callMe(id: Int) async throws {
        print("\(id) called")
        
        if let existingTask = currentTask {
            // 已有任务在运行,等待任务完成
            try await existingTask.value
        } else {
            // 无任务运行,创建新任务执行异步工作
            print("\(id) is going to start doing something useful")
            let task = Task {
                try await self.doSomeAsyncStuff()
            }
            currentTask = task
            
            do {
                try await task.value
            } catch {
                // 传递任务执行中的错误
                throw error
            } finally {
                // 任务完成(成功/失败)后清空任务引用
                currentTask = nil
            }
        }
    }
    
    private func doSomeAsyncStuff() async throws {
        try await Task.sleep(nanoseconds: 1_000_000_000)
        print("finished doing something useful")
    }
}

调用代码

let test = NewTest()

// 用TaskGroup替代concurrentPerform,适配Swift Concurrency异步模型
Task {
    await withTaskGroup(of: Void.self) { group in
        for i in 0..<3 {
            group.addTask {
                try await test.callMe(id: i)
                print("\(i) is done")
            }
        }
    }
}

核心逻辑输出(调度顺序可能略有差异,但核心行为一致)

0 called
0 is going to start doing something useful
1 called
2 called
finished doing something useful
0 is done
1 is done
2 is done
方案说明
  1. 任务引用管理:通过currentTask存储当前运行的异步任务,确保同一时间仅一个任务执行。
  2. 自动等待机制:后续请求发现已有任务时,直接await任务结果,无需手动存储回调,Swift异步语法自动完成结果传递。
  3. 错误一致性:任务执行中的错误会通过try await传递给所有等待的请求,保证所有请求拿到相同的错误信息。
  4. 资源清理:在finally块中清空任务引用,确保任务完成后Actor可以接受新的请求触发任务。

该方案完全基于Swift Concurrency框架,无需依赖GCD,完美复刻原模式的核心行为:合并重复请求、避免任务重复执行、所有请求等待任务完成后统一返回结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 09:52:45