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
相关产品推荐
相关产品推荐

