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

如何正确获取URLSession异步请求返回值用于后续计算存储

问题根因

你遇到的是异步函数同步返回的典型问题:

  • URLSession.dataTask 属于异步执行逻辑,fetchData 的completion闭包会在网络请求完成后才触发,执行时机远晚于getGainLossNumber的return操作
  • 你声明finalPrice = 0.0后立刻执行了return,此时闭包还没拿到网络返回结果,自然永远返回初始值0

解决方案1:沿用回调模式(兼容旧版Swift)

把getGainLossNumber也改成异步回调的形式,不直接返回值,而是通过completion传递计算结果:

func getGainLossNumber(brand: String, quantity: Int, price: Double, completion: @escaping (Double) -> Void) {
    APImodel.fetchData(brand: brand) { returnedDouble in
        let currentPrice = returnedDouble
        let finalPrice: Double
        if quantity < 0 {
            let orderQuantity = quantity * -1
            finalPrice = price + (currentPrice * Double(orderQuantity) * 100)
        } else {
            finalPrice = price - (currentPrice * Double(quantity) * 100)
        }
        completion(finalPrice)
    }
}

调用时通过闭包接收结果即可:

// 调用示例
getGainLossNumber(brand: "目标品牌", quantity: 10, price: 5.0) { finalPrice in
    // 拿到计算结果后再执行后续操作,比如存CoreData、刷新UI
    // 注意如果要操作UI需要切回主线程:DispatchQueue.main.async { 你的UI逻辑 }
}

解决方案2:使用Swift Concurrency(Swift 5.5+ 推荐)

如果你的项目支持iOS 15+/macOS 12+,可以用async/await改写异步逻辑,避免回调嵌套,写法更直观:
首先改写fetchData为async版本:

func fetchData(brand: String) async throws -> Double {
    let urlString = "\(quoteUrl)\(brand)"
    guard let url = URL(string: urlString) else {
        throw NSError(domain: "InvalidURL", code: -1)
    }
    var request = URLRequest(url: url)
    request.addValue("application/json", forHTTPHeaderField: "Accept")
    request.addValue("Bearer \(key)", forHTTPHeaderField: "Authorization")
    let (data, _) = try await URLSession.shared.data(for: request)
    let decodedData = try JSONDecoder().decode(DataModel.self, from: data)
    let bid = decodedData.quotes.quote.bid
    let ask = decodedData.quotes.quote.ask
    return (bid + ask) / 2
}

对应改写getGainLossNumber:

func getGainLossNumber(brand: String, quantity: Int, price: Double) async throws -> Double {
    let currentPrice = try await APImodel.fetchData(brand: brand)
    if quantity < 0 {
        let orderQuantity = quantity * -1
        return price + (currentPrice * Double(orderQuantity) * 100)
    } else {
        return price - (currentPrice * Double(quantity) * 100)
    }
}

调用方式:

Task {
    do {
        let finalPrice = try await getGainLossNumber(brand: "目标品牌", quantity: 10, price: 5.0)
        // 拿到结果后处理后续逻辑
    } catch {
        // 处理网络请求、解析等异常
        print(error)
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 05:06:04