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

Swift中如何等待异步函数返回结果?附代码问题示例

解决异步请求未完成就返回的问题

你的问题核心是fetchProfilesForList函数里的所有fetchProfile都是异步操作,函数会在这些异步请求返回结果前就执行到completion语句,导致返回空数组。可以通过DispatchGroup来等待所有异步请求完成后再返回结果,具体修改如下:

修改后的ViewModel代码

func addNoteToList(title: String, note: String) {
    guard let id = self.listID, let userID = profileID else {
        return
    }
    
    fm.fetchProfile(uid: userID) { [self] profile in
        print("FETCHED USER PROFILE FOR SHORTCUT")
        
        fm.fetchList(uid: id) { [self] list in
            print("FETCHED LIST FOR SHORTCUT")
            
            fetchProfilesForList(list: list) { profiles in
                print("users retuned \(profiles.count)")
                
                for p in profiles {
                    print("ADD NOTE TO LIST SHORTCUT")
                    
                    // 创建Payment
                    let note = Payment(title: title, note: note, user: p.uid)
                    
                    // 添加到列表并更新
                    var updatedList = list
                    updatedList.notes.append(note)
                    self.fm.updateList(updatedList)
                }
            }
        }
    }
}

func fetchProfilesForList(list: List, completion: @escaping ([Profile]) -> Void) {
    var groupProfiles: [Profile] = []
    let dispatchGroup = DispatchGroup()
    
    // 处理管理员逻辑(如果当前用户不是管理员且在群组中)
    if list.admin != profileID, let currentProfileID = profileID, list.group.contains(currentProfileID) {
        print("IS NOT ADMIN and add to note")
        
        dispatchGroup.enter()
        fm.fetchProfile(uid: list.admin) { admin in
            print("FETCHED ADMIN")
            groupProfiles.append(admin)
            dispatchGroup.leave()
        }
    }
    
    // 遍历群组中的用户,获取除当前用户外的其他用户资料
    for p in list.group {
        guard let currentProfileID = profileID, p != currentProfileID else {
            continue
        }
        
        dispatchGroup.enter()
        fm.fetchProfile(uid: p) { profile in
            print("profile \(profile.firstName)")
            groupProfiles.append(profile)
            dispatchGroup.leave()
        }
    }
    
    // 等待所有异步请求完成后,处理结果并返回
    dispatchGroup.notify(queue: .main) {
        let uniqueUsers = groupProfiles.removeDuplicates()
        completion(uniqueUsers)
    }
}

关键修改点说明

  • 使用DispatchGroup:每个fetchProfile调用前调用enter(),在回调完成后调用leave(),确保所有异步操作都完成后才执行后续逻辑。
  • 修复变量错误:原代码中people.append(admin)是笔误,改为添加到目标数组groupProfiles;原completion(p)修正为传入处理后的去重数组uniqueUsers。
  • 可选值安全处理:用guard let替代强制解包,避免潜在崩溃风险。
  • 代码结构优化:将嵌套的if let改为guard let,让代码逻辑更清晰易读。

额外提示

确保你的removeDuplicates()自定义方法是基于Profile的唯一标识(比如uid)来实现去重,避免重复添加同一用户的资料。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 04:05:09