/* Page prose (zh-Hans) */
"WrappingUp" = "# 小结\n\n依赖为你换来了正确的顺序，以及操作之间无竞争的数据交接；取消和由回调驱动的工作，才是手动记账堆积起来的地方。下面几乎每一个陷阱，都是一个你必须靠自己记住的步骤：检查取消标志，在每一条路径上到达 **finished**，防范一个被取消的依赖。留意需要记住的东西有多少，因为这种记账*恰恰*是现代 Swift 并发所自动化的东西，而现代模型正是你终于把它放下的地方。\n\n* `addDependency(_:)` 强制顺序：一个依赖方在它的所有依赖都报告 `isFinished` 之前不会启动，但它只排序工作，不搬运数据。你要自己把输出接到前面去，并在使用之前防范一个**被取消的依赖**（它仍然“完成了”，输出却可能是 `nil`）。\n* 因为一个依赖在时间上把两个操作完全分开，把数据从一个传到下一个是无竞争的。让依赖朝一个方向流动：一个环会让两个操作永远都不*ready*。\n* 取消是**协作式**的：`cancel()` 只设置 `isCancelled`。你的 `main()` 必须在慢步骤之前和循环内部检查这个标志，并提早返回，否则什么都不会停下来。\n* 一个普通的 `Operation` 在 `main()` 返回的那一刻就“完成了”，这对于在稍后回调里才完成的工作是错的。\n* 一个**异步操作**重写 `isAsynchronous`，手动驱动 `ready → executing → finished` 状态机，并触发 KVO 通知让队列注意到。它必须在每一条路径上到达 **finished**，取消也包括在内，否则队列会堵在它后面，并且要在回调里捕获 `[weak self]`。\n* `completionBlock` 在一个操作完成之后运行，在某个线程上，甚至对被取消的操作也会运行。\n\n---\n\n## 接下来\n\n下一章，[为什么需要现代并发](Why%20Modern%20Concurrency.playgroundchapter/Overview)，展示了现代并发为什么存在：回调问题被彻底揭示，以及结构化并发对你刚刚亲手构建的一切修复了什么。\n\n[上一页](@previous)  |  第 7 / 7 页";
