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

SwiftUI异步函数执行问题:添加购物车后商品数量与总价不同步

SwiftUI购物车添加商品后总价与数量不同步问题

问题描述

添加商品至购物车后,总价计算未同步更新购物车内商品数量。例如当前购物车商品数量为4,添加商品后控制台打印数量仍为4并据此计算总价,但后台实际购物车商品已增至5。

问题代码

@Published var cartProducts = [CartProduct]()
private let httpDownloader = HttpDownloader()
@Published var cartItemCount = 0
@Published var totalAmount: Double = 0

func getUserProducts() {
    httpDownloader.fetchUserProducts() { (result) in
        switch result {

        case .success(let cartProducts):
            if let cartProducts = cartProducts {
                DispatchQueue.main.async {
                    self.cartProducts = cartProducts
                }
            }

        case .failure(let error):
            print("Error fetching products: \(error)")
        }
    }
}

func addProductToCart(id: Int, quantity: Int) {
    httpDownloader.addProductToCart(productId: id, quantity: quantity) { result in
        switch result {

        case .success:
            DispatchQueue.main.async {
                self.getUserProducts()

                print(self.cartProducts.first?.quantity ?? 0)

                self.calculateTotalPrice(products: self.cartProducts)
            }
        case .failure(let error):
            print("Error fetching products: \(error)")
        }
    }
}

问题根源

getUserProducts 内部是异步网络请求,调用后会立即返回,后续的 print 和 calculateTotalPrice 会直接执行——此时网络请求尚未完成,cartProducts 还是更新前的旧数据,导致计算结果与后台实际数据不符。

解决方案

方案1:将计算逻辑移至异步请求完成后

修改 getUserProducts,在更新 cartProducts 后立刻执行总价计算和数量打印:

func getUserProducts() {
    httpDownloader.fetchUserProducts() { (result) in
        switch result {
        case .success(let cartProducts):
            if let cartProducts = cartProducts {
                DispatchQueue.main.async {
                    self.cartProducts = cartProducts
                    // 同步计算总价
                    self.calculateTotalPrice(products: cartProducts)
                    // 打印最新数量
                    print(self.cartProducts.first?.quantity ?? 0)
                }
            }
        case .failure(let error):
            print("Error fetching products: \(error)")
        }
    }
}

同时简化 addProductToCart,移除提前执行的计算逻辑:

func addProductToCart(id: Int, quantity: Int) {
    httpDownloader.addProductToCart(productId: id, quantity: quantity) { result in
        switch result {
        case .success:
            DispatchQueue.main.async {
                self.getUserProducts()
            }
        case .failure(let error):
            print("Error adding product to cart: \(error)")
        }
    }
}

方案2:利用属性监听自动触发计算

给 cartProducts 添加 didSet 监听,只要数组更新就自动计算总价和商品数量:

@Published var cartProducts = [CartProduct]() {
    didSet {
        // 自动计算总价
        calculateTotalPrice(products: cartProducts)
        // 自动统计购物车总商品数量(如果需要)
        cartItemCount = cartProducts.reduce(0) { $0 + $1.quantity }
    }
}

这种方式下,getUserProducts 只需负责更新 cartProducts,无需额外调用计算方法;addProductToCart 保持调用 getUserProducts 即可,所有计算逻辑会在数据更新后自动触发。

内容的提问来源于stack exchange,提问作者Mehmet Özkan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 00:15:58