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

如何将含递归的Completion Handler函数转换为Async函数?

将基于Completion的递归函数转换为Async/Await函数

问题背景

原来的函数通过completion回调实现递归数据获取:

func myFunction(currentList: [String] = [], startIndex: Int = 0, completion: @escaping ([String]) -> Void) {
    var list = currentList
    let maxSize = 10
    let endIndex = startIndex + maxSize - 1
    privateFunction(range: startIndex...endIndex) { items in
        list.append(contentsOf: items)
        if items.count < maxSize {
            completion(list)
        } else {
            myFunction(currentList: list, startIndex: startIndex + maxSize, completion: completion)
        }
    }
}

需要将其转换为支持async/await的版本,已尝试用withCheckedContinuation改造,但递归分支的实现存疑。

解决方案

核心思路是在递归分支中,通过Task异步调用新版的async函数,拿到最终递归结果后再resume continuation:

func myFunction(currentList: [String] = [], startIndex: Int = 0) async -> [String] {
    var list = currentList
    let maxSize = 10
    let endIndex = startIndex + maxSize - 1
    
    return await withCheckedContinuation { continuation in
        privateFunction(range: startIndex...endIndex) { items in
            list.append(contentsOf: items)
            
            if items.count < maxSize {
                // 数据已取完,直接返回结果
                continuation.resume(returning: list)
            } else {
                // 递归调用async版本,拿到最终结果后resume
                Task {
                    let finalList = await myFunction(currentList: list, startIndex: startIndex + maxSize)
                    continuation.resume(returning: finalList)
                }
            }
        }
    }
}

关键细节说明

  1. 修正笔误与逻辑错误:

    • 原代码中start应为startIndex,否则会出现未定义变量错误
    • 原代码用list.append(items)会将整个items数组作为单个元素添加,需改为append(contentsOf: items)才能正确合并数组
  2. 递归分支处理:
    由于privateFunction的回调是同步上下文,无法直接在其中使用await,因此通过Task开启异步任务执行递归调用,待递归完成拿到最终结果后,再调用continuation.resume(returning:)传递结果,确保withCheckedContinuation仅被resume一次,符合其使用规范。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 21:06:22