探讨在withCheckedContinuation的resume后执行代码的潜在问题
关于Checked Continuation调用resume后执行代码的潜在问题
这种写法确实存在不少潜在风险,具体影响如下:
执行顺序不可控,引发逻辑混乱
调用continuation.resume()后,异步函数的调用者会立即被唤醒继续执行,此时调用者的代码和resume()后的doSomething()可能处于并行执行状态。如果doSomething()涉及和返回值相关的状态操作,很容易出现竞态条件,导致业务逻辑不符合预期。比如调用者可能在doSomething()完成前就拿到返回值并执行后续步骤,破坏原本的依赖关系。阻塞调度队列,影响性能
如果doSomething()是耗时操作,它会占用当前执行resume()的线程或队列。如果这个队列是主队列这类串行队列,会直接阻塞后续任务,降低应用响应性;即便是并发队列,也会占用不必要的资源,影响整体并发效率。违反并发模型,增加维护成本
Checked Continuation的设计初衷是让你在完成异步任务后调用resume(),之后应尽快退出闭包,避免额外逻辑。这种resume后执行代码的写法属于反模式,会让代码的执行流程变得晦涩,其他开发者阅读或调试时容易误解逻辑,后续维护难度大大提升。
修正建议
如果doSomething()和异步任务的结果无关,建议将其移到resume()之前执行;如果确实需要在resume后执行,应该将其调度到独立的队列中,避免干扰异步函数的执行流程:
func myAsyncMethod() async -> Bool { withCheckedContinuation { continuation in // 优先执行不依赖resume的逻辑 doSomething(value: true) continuation.resume(returning: true) // 必须在resume后执行的话,调度到指定队列 DispatchQueue.global().async { doSomething(value: true) } } }
内容的提问来源于stack exchange,提问作者Aleš Kocur
相关产品推荐
相关产品推荐

