欢迎使用 CollectionConcurrencyKit,这是一个轻量级的 Swift 包,它为所有符合 Sequence 协议的 Swift 集合添加了异步和并发版本的标准 map、flatMap、compactMap 和 forEach API。 这包括内置类型,如 Array、Set 和 Dictionary,以及任何符合该协议的自定义集合。
CollectionConcurrencyKit 可用于以充分利用 Swift 内置并发系统的方式实现高性能数据处理和算法。 它经过了大量的单元测试,拥有完整的文档,并且已在生产环境中用于生成 swiftbysundell.com。
CollectionConcurrencyKit 的 API 的异步变体使您能够在各种映射和 forEach 迭代中调用标记为 async 的函数,同时仍然保持完全可预测的顺序执行。
例如,以下是我们如何使用 asyncMap 从 URL 集合下载一系列 HTML 字符串
let urls = [
URL(string: "https://apple.com")!,
URL(string: "https://swiftlang.cn")!,
URL(string: "https://swiftbysundell.com")!
]
let htmlStrings = try await urls.asyncMap { url -> String in
let (data, _) = try await URLSession.shared.data(from: url)
return String(decoding: data, as: UTF8.self)
}
以下是我们如何使用 asyncCompactMap 通过返回一个可选值而不是抛出错误来忽略任何下载失败
let htmlStrings = await urls.asyncCompactMap { url -> String? in
do {
let (data, _) = try await URLSession.shared.data(from: url)
return String(decoding: data, as: UTF8.self)
} catch {
return nil
}
}
CollectionConcurrencyKit 的每个 API 都提供抛出和非抛出变体,因此由于上面对 asyncCompactMap 的调用不会抛出,因此我们在调用它时无需使用 try。
CollectionConcurrencyKit 还包括 forEach、map、flatMap 和 compactMap 的并发变体,它们并行执行迭代,同时在生成结果时仍然保持可预测的顺序。
例如,由于我们的上述 HTML 下载代码由完全独立的操作组成,我们可以使用 concurrentMap 并行执行每个操作,从而显着提高速度
let htmlStrings = try await urls.concurrentMap { url -> String in
let (data, _) = try await URLSession.shared.data(from: url)
return String(decoding: data, as: UTF8.self)
}
如果我们想并行化基于 asyncCompactMap 的上述代码变体,那么我们可以使用 concurrentCompactMap 来做到这一点
let htmlStrings = await urls.concurrentCompactMap { url -> String? in
do {
let (data, _) = try await URLSession.shared.data(from: url)
return String(decoding: data, as: UTF8.self)
} catch {
return nil
}
}
无论我们选择 CollectionConcurrencyKit 的 API 的异步版本还是并发版本,返回结果的顺序始终保证与调用标准库的非异步版本 API 时完全相同。 因此,htmlStrings 数组的顺序在上述所有四个代码示例中都是相同的(忽略 compactMap 变体产生的任何 nil 值)。
CollectionConcurrencyKit 将以下 API 添加到所有符合 Sequence 协议的 Swift 集合中
asyncForEachasyncMapasyncCompactMapasyncFlatMapconcurrentForEachconcurrentMapconcurrentCompactMapconcurrentFlatMap包括上述所有 API 的抛出和非抛出版本。 要了解有关 map、flatMap 和 compactMap 的更多信息,请查看本文。
CollectionConcurrencyKit 适用于所有支持 Swift 并发系统的操作系统版本,目前包括 iOS 15、macOS 12、watchOS 8 和 tvOS 15,以及 Linux(当使用 5.5 或更高版本的 Swift 工具链时)。
Apple 目前正在努力为 Swift 的并发系统添加向后兼容性,一旦该功能完全可用(目前在测试版中,作为 Xcode 13.2 的一部分),CollectionConcurrencyKit 也将更新以支持更早的 OS 版本。
CollectionConcurrencyKit 是使用 Swift Package Manager 分发的。 要在另一个 Swift 包中安装它,请在您的 Package.swift 清单中将其添加为依赖项
let package = Package(
...
dependencies: [
.package(url: "https://github.com/JohnSundell/CollectionConcurrencyKit.git", from: "0.1.0")
],
...
)
如果您想在 iOS、macOS、watchOS 或 tvOS 应用程序中使用 CollectionConcurrencyKit,请使用 Xcode 的 File > Add Packages... 菜单命令将其添加到您的项目中。
然后在任何你想使用它的地方导入 CollectionConcurrencyKit
import CollectionConcurrencyKit
有关如何使用 Swift Package Manager 的更多信息,请查看 本文,或 其官方文档。
CollectionConcurrencyKit 已根据非常宽松的 MIT 许可证 免费提供给整个 Swift 社区,但请注意,它不附带任何官方支持渠道,例如 GitHub 问题或基于 Twitter/电子邮件的支持。 因此,在您开始在您的项目中使用 CollectionConcurrencyKit 之前,强烈建议您花一些时间熟悉 它的实现,以防您遇到任何需要调试的问题。
如果您发现了一个错误、文档拼写错误,或者想要提出性能改进建议,请随时 打开一个 Pull Request(即使它只包含一个重现给定问题的单元测试)。 欢迎各种修复和调整,但 CollectionConcurrencyKit 旨在成为一个非常小巧且专注的库,因此它被认为是或多或少功能完整的。 因此,如果您想向该库添加任何重要的新功能,建议您 fork 它,这将允许您扩展和自定义它以满足您的需求。
希望您喜欢使用 CollectionConcurrencyKit!