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

Swift基于actor/async/await实现仅留最新待执行任务串行队列咨询

问题分析

你写的实现离目标逻辑有几个明显的偏差,直接运行会出现不符合预期的行为:

  • 返回值时序错误:创建完处理Task后立刻读取latestResult返回,此时Task还没开始执行,拿到的永远是上一次任务的结果,不是本次请求对应的处理返回值。
  • 重复创建任务的竞态:多个analyseItem调用会同时在await task?.value处等待,等前一个任务执行完后,这些等待的调用会依次继续执行,重复创建多个新的处理任务,打破串行执行的规则。
  • 丢弃逻辑不完整:没有区分「当前有任务正在执行」和「当前空闲」的状态,空闲状态下新入队的任务不需要等待,应该立刻启动;同时任务执行完成后没有清空待执行项的残留值,下次启动会误处理过期的旧任务。
符合需求的实现方案

你要做的是最经典的丢弃中间任务的串行执行器,核心规则是同一时间最多跑1个任务,执行期间新来的请求只留最新的一个待执行,中间的全部丢弃,当前任务跑完后如果有待执行项就接着跑最新的,没有就回到空闲。
修正后的代码如下:

// 替换成你自己的Item定义即可
protocol Item {
    func processItem() -> Bool
}

actor Worker {
    // 标记当前是否有正在运行的处理任务
    private var currentRunningTask: Task<Void, Never>?
    // 存当前任务执行期间收到的最新待处理项,默认nil表示没有待执行任务
    private var latestPendingItem: Item?
    
    @discardableResult
    func analyseItem(_ item: Item) async -> Bool? {
        // 新请求进来直接覆盖待处理项,之前没来得及跑的旧待处理项自动丢弃
        latestPendingItem = item
        
        // 如果现在已经有任务在跑,等它跑完就行,不用重复启动任务
        if let runningTask = currentRunningTask {
            await runningTask.value
            // 可自行扩展:判断当前item是否被覆盖,返回特定标识告知调用方任务被丢弃
            return nil
        }
        
        // 没有正在跑的任务,启动执行循环
        let processTask = Task { [weak self] in
            guard let self else { return }
            // 循环处理:只要还有待处理的最新项,就一直执行,直到没有待处理项为止
            while let itemToProcess = self.latestPendingItem {
                // 取到待处理项立刻清空标记,执行过程中新来的请求会重新给latestPendingItem赋值
                self.latestPendingItem = nil
                // 执行实际的处理逻辑
                _ = itemToProcess.processItem()
            }
            // 所有待处理项执行完,清空运行标记,回到空闲状态
            self.currentRunningTask = nil
        }
        currentRunningTask = processTask
        await processTask.value
        
        return nil
    }
}

补充说明:如果你需要每个调用analyseItem的地方都能拿到自己请求对应的处理结果(而不是被丢弃),需要给每个入队请求维护对应的CheckedContinuation,当待执行项被新请求覆盖时,提前结束旧请求的Continuation(比如返回nil或者自定义的任务被丢弃的错误),避免调用方无限挂起。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 11:51:21