如何用Operation Queue为订单计数器实现延迟提交逻辑?
用Operation Queue实现点击合并提交逻辑
核心思路
每次点击按钮时先累加计数器,同时取消之前排队的提交操作,再重新创建一个延迟1秒执行的提交操作。这样快速连续点击时,旧的提交操作会被不断取消,只有最后一次点击后等待1秒无新操作时,才会将累计的计数器值一次性提交到服务器。
完整实现代码
import UIKit class YourViewController: UIViewController { // 商品数量计数器 var counter = 0 // 管理提交操作的队列 private let submitQueue = OperationQueue() // 保存当前待执行的提交操作,用于后续取消 private var pendingSubmitOperation: BlockOperation? @IBAction func addProductAmount(_ sender: Any) { // 1. 累加计数器 counter += 1 // 2. 取消之前未执行的提交操作 pendingSubmitOperation?.cancel() // 3. 创建新的提交操作,延迟1秒执行 pendingSubmitOperation = BlockOperation { [weak self] in guard let self = self, !self.pendingSubmitOperation!.isCancelled else { return } // 模拟1秒延迟(后台执行,不阻塞主线程) Thread.sleep(forTimeInterval: 1) // 再次检查是否被取消(防止延迟期间有新点击) guard !self.pendingSubmitOperation!.isCancelled else { return } // 4. 提交到服务器(替换为你的实际网络请求代码) DispatchQueue.main.async { print("提交商品数量到服务器:\(self.counter)") // 提交完成后重置计数器 self.counter = 0 } } // 将操作加入队列执行 submitQueue.addOperation(pendingSubmitOperation!) } }
关键细节说明
submitQueue:专门管理提交操作的队列,默认是并行队列,但由于每次都会取消前序操作,实际只会有一个待执行的提交任务,确保提交逻辑在后台执行,不阻塞主线程。pendingSubmitOperation:追踪当前等待执行的提交操作,每次新点击时取消它,避免旧操作触发重复提交。- 延迟逻辑:用
Thread.sleep(forTimeInterval: 1)在后台操作中实现延迟,也可以替换为DispatchQueue.global().asyncAfter(deadline: .now() + 1),效果一致且更灵活。 - 弱引用
self:避免BlockOperation持有ViewController导致循环引用,保证内存安全。 - 计数器重置:提交完成后归零计数器,确保下次点击重新开始计数。
内容的提问来源于stack exchange,提问作者incelemeTRe
相关产品推荐
相关产品推荐

