在 Swift(乃至整个并发世界)里:
如果你真正理解了 continuation,你就理解了 async/await 的底层本质。
我会按 概念 → Swift 里的具体形态 → 与 async/await 的关系 → 常见误区 来讲。
一句话定义(先刻在脑子里)
Continuation =「从当前点开始,程序接下来该怎么继续执行」的一个可保存、可传递、可稍后调用的对象。
换句话说:
continuation 就是 “未来的自己” 。
1️⃣ 直观理解(不用术语)
看这段代码:
let x = await foo()
print(x)
在 await foo() 这一行:
- 当前函数不能继续往下跑
- 但“等 foo 完成之后该干什么”是完全确定的
这段“之后该干什么”的逻辑:
print(x)
👉 这就是一个 continuation
2️⃣ continuation 在 Swift 中到底是什么?
在 Swift Concurrency 里,continuation 不是抽象概念,而是真实存在的东西:
在编译器 / runtime 层面
continuation 由以下几部分组成:
-
resume function
- 一个函数指针
- 指向“await 之后的代码块”
-
async context
- 保存局部变量、状态机状态
-
executor 信息
- 决定在哪里恢复执行
合在一起:
continuation =
(async context + resume entry + executor)
3️⃣ async/await 和 continuation 的关系(核心)
❓ async/await 做了什么?
async/await 的本质就是:
把 continuation 自动、隐式地帮你创建和管理了。
不用 async/await(手写 continuation)
func foo(_ cont: @escaping (Int) -> Void) {
bar { result in
cont(result + 1)
}
}
你在手动传递 continuation。
用 async/await
func foo() async -> Int {
let x = await bar()
return x + 1
}
编译器在背后自动做了:
- 创建 continuation
- 保存当前上下文
- 把 continuation 传给
bar - 在合适的 executor 上 resume
👉 你写的是顺序代码,底层仍然是 continuation。
4️⃣ withUnsafeContinuation 是什么角色?
这是 Swift 暴露给用户的 continuation API。
func legacy() async -> Int {
await withCheckedContinuation { cont in
legacyAPI { value in
cont.resume(returning: value)
}
}
}
这里:
-
cont就是当前 async 函数的 continuation -
调用
resume:- 就等于“触发 await 后面的代码继续执行”
⚠️ 注意:
resume只能调用一次- 否则 continuation 会崩(checked 版会直接 trap)
5️⃣ continuation 与“状态机”的关系
continuation ≠ 状态机
continuation = 状态机的一个“入口点”
-
状态机:
- 决定你现在在哪个状态
-
continuation:
- 是“从这个状态继续跑”的 callable handle
你可以把它理解为:
state machine + continuation = coroutine
6️⃣ continuation 与线程的关系(常见误解)
❌ 错误理解
continuation = 保存当前线程
✅ 正确理解
continuation 不保存线程,只保存“逻辑上的下一步”。
-
恢复时:
- 可能在同一个线程
- 也可能在完全不同的线程
-
线程由 executor 决定
7️⃣ continuation 在错误、取消中的作用
错误传播
await foo() // throws
-
continuation 包含:
- normal resume
- error resume
cancellation
-
task 被取消时
-
runtime 会:
- 找到 continuation
- 恢复执行
- 抛出
CancellationError
8️⃣ 和其他语言的对比(帮助定位)
| 语言 | continuation 表现 |
|---|---|
| Swift | 隐式 + 显式(withContinuation) |
| Kotlin | Continuation<T> 参数 |
| JS | Promise.then |
| C++20 | coroutine_handle |
| Scheme | call/cc |
Swift 的设计目标是:
让 99% 的 continuation 消失在语法糖后面
9️⃣ 终极记忆版总结
Continuation 是“await 之后要做什么”的可执行表示。
async/await 的全部魔法,就是把 continuation 自动保存、传递、恢复。