Task.sleep 是 Swift Concurrency 提供的一个异步挂起函数,用来让当前任务暂停一段时间,属于 Task 类型的静态方法。
它只能在 async 函数中使用,并且是非阻塞的(不会阻塞线程)。
本质是暂停当前任务,检查是否取消,如果没有取消则继续,取消则抛出错误。
旧版本(早期Swift并发):
try await Task.sleep(nanoseconds: 1_000_000_000) // 暂停 1 秒
要求必须传入纳秒 UInt 64。
新版本(Swift 5.9以后):
Swift允许使用基于 Duration 类型的 API:
1、挂起500毫秒:
try await Task.sleep(for: .milliseconds(500))
2、挂起2秒;
try await Task.sleep(for: .seconds(2))
3、使用Duration保存挂起秒数:
let d: Duration = .seconds(2)
try await Task.sleep(for: d)
使用方法
代码示例:
Task {
print("开始任务")
try await Task.sleep(nanoseconds: 2_000_000_000)
print("两秒后执行")
}
Task {} 创建了一个新的异步任务。
Task.sleep(…) 让当前任务“挂起”2秒。
挂起期间线程是空闲的,可以执行别的任务。
Task.sleep 为什么需要 try?
Task.sleep 遵守 Swift并发的原则:挂起点必须对取消敏感。
Task在sleep期间被取消时,Task必须停止暂停任务,并理解抛出取消错误。
do {
try await Task.sleep(for: .seconds(3))
print("正常醒来")
} catch {
print("被取消了")
return
}
Task.sleep不会因为时间设置错误而throw,只有取消Task时,才会抛出错误。
Task.sleep和Task.checkCancellation的区别
Task.checkCancellation用于主动检查任务是否被取消,相当于手动检查任务是否被取消,如果取消则抛出错误,提前中止任务执行。
Task.sleep暂停任务时,不需要使用Task.checkCancellation手动检查。因为如果任务被取消,slepp会自己处理并抛出错误。
Swift并发是协作式取消:如果Task被取消,Task内部会检查当前是否为Task.sleep,如果没有则会继续执行,直到遇到Task.checkCancellation时,才会检查取消状态。
Task.sleep和Thread.sleep()的区别
1、Task.sleep:类型是异步挂起,不会阻塞线程,并且支持取消。
2、Thread.sleep:类型是同步阻塞,会阻塞当前现场,不可取消。
在 Swift 并发中,应尽量避免用 Thread.sleep(),而应该使用 Task.sleep()。
取消Task.sleep
取消Task.sleep代码示例:
var task: Task<Void,Never>?
func createTask() {
task = Task {
try await Task.sleep(nanoseconds: 5_000_000_000)
print("我醒了")
}
}
func canceTask() {
task?.cancel() // 取消任务
}
Task.sleep 会响应取消,所以任务没有等完 5 秒就结束了,不会输出“我醒了”。
总结
Task.sleep会暂停当前任务,如果Task被取消,则会抛出Task.checkCancellation错误。
使用 Task.sleep 可以实现非阻塞延迟,配合 SwiftUI 的异步环境更新视图状态。
常用于异步等待的场景,例如等待接口信息返回、等待银行出账等场景。
相关文章
1、Swift并发模型中的Task:https://fangjunyu.com/2025/05/15/swift%e5%b9%b6%e5%8f%91%e6%a8%a1%e5%9e%8b%e4%b8%ad%e7%9a%84task/
