Meet Swift Async Algorithms
Swift & UI 进阶 20m

认识 Swift Async Algorithms

Meet Swift Async Algorithms

2022年6月6日

在 Apple 官方观看视频

一句话判断

Swift Async Algorithms 为 AsyncSequence 补齐了 Zip、Merge、Debounce、Chunk 等高级算法,配合 Swift 5.7 的新 Clock API,处理异步事件流从未如此优雅。

这场 Session 讲了什么

去年 Swift 引入了 AsyncSequence,提供了 map、filter、reduce 等基础算法。Swift Async Algorithms 包填补了高级算法的空白。这是一个开源包,和 Swift Collections、Swift Algorithms 并列。

Session 用一个即时通讯 App 的迁移案例串联了所有核心算法。Zip 用于并发等待多个异步操作完成(视频转码 + 预览生成)。Merge 用于合并多个账号的消息流。Debounce 用于搜索输入的防抖。Buffer 和 Chunk 用于消息的批量处理。

下半部分深入讲解了 Swift 5.7 引入的 Clock、Instant、Duration 体系,以及 ContinuousClock(秒表式计时)和 SuspendingClock(机器休眠时暂停)的区别。这些时间原语是 Async Algorithms 中所有时间相关算法的基础。

值得深挖的点

  • Zip 的并发执行:与标准库的 Zip 不同,AsyncSequence 的 Zip 并发迭代各个 base,不会互相阻塞。视频转码和预览生成可以同时进行,Zip 等待两者都完成后返回一个元组。
  • Merge 的合并策略:多个 AsyncSequence 合并为一个流,谁先产出值就先发出。任何一个 base 出错,其他迭代会被取消。适合多账号消息合并场景。
  • Debounce 和 Throttle 的区别:Debounce 等待一段静默期后发出最后一个值——适合搜索输入。Throttle 按固定间隔发出值——适合限流。两者都基于新的 Clock API。
  • ContinuousClock vs SuspendingClock:ContinuousClock 像 stopwatch,机器休眠后时间继续流逝。SuspendingClock 在机器休眠时暂停。动画用 SuspendingClock,面向人的延时用 ContinuousClock。

代码片段

import AsyncAlgorithms

// Zip:并发等待视频转码和预览生成
let transcoded = transcodeVideo(video)    // AsyncSequence
let preview = generatePreview(video)      // AsyncSequence
for await (video, thumb) in zip(transcoded, preview) {
    // 两者都完成后一起上传
    upload(video: video, thumbnail: thumb)
}

// Merge:合并多个账号的消息流
let streams = accounts.map { account in
    AsyncStream<Message> { continuation in
        account.onMessage { message in
            continuation.yield(message)
        }
    }
}
let allMessages = merge(streams)
for await message in allMessages {
    display(message)
}

// Debounce:搜索防抖
let searchResults = searchTextChannel
    .debounce(for: .milliseconds(300), clock: .continuous)
    .map { query in
        try await searchService.search(query)
    }

// Clock 的使用
let clock = ContinuousClock()
let elapsed = try await clock.measure {
    try await performWork()
}
print("耗时: \(elapsed)")

最佳实践

  • 异步操作需要等待多个结果时优先考虑 Zip,不要手动用 TaskGroup 模拟
  • 处理用户输入时用 Debounce 而非手动计时器
  • 面向人的时间相关逻辑用 ContinuousClock,面向设备/动画的用 SuspendingClock
  • Merge 多个 AsyncSequence 时确保元素类型一致
  • 这个包是开源的,可以在 GitHub 上查看源码和提案

还有什么值得关注

  • “Meet AsyncSequence”(WWDC 2021)是前置内容
  • Swift Clock API 是 Swift 5.7 的一部分,不需要额外依赖
  • Async Algorithms 包还在持续演进,未来会有更多算法加入
  • 这个包特别适合实时数据处理场景:传感器数据、股票行情、聊天消息等
WWDC 2022