Futures 是一个轻量级的、通用的 Swift 异步编程库,它提供了一组可互操作的原语,以帮助开发高度并发、高性能和安全的程序,无论是在服务器端、桌面端还是移动端。Futures 采用了一种“拉取”式、需求驱动的方法进行异步编程,除了提供惊人的性能外,还可以轻松处理诸如反压、取消和线程等传统上难以解决的问题。
Swift 中已经存在大量用于异步编程的库。 许多都是优秀的库,如果您正在寻找适合您需求的抽象,您应该认真考虑它们。 那么您为什么要关心 Futures 呢?
您会发现 Futures...
Subject
,谢谢)。请继续阅读,还有更多内容
这是一个小程序,用于计算生命、宇宙和一切的终极问题的答案。
import Futures
let integers = Stream.sequence(0...)
let primes = integers.filter(isPrime)
var answer = primes.buffer(4)
.map { $0[0] * $0[1] * $0[3] }
.first(where: isPronic)
print(answer.wait()) // prints 42
这是一个经过精心设计过的程序,可以展示 Futures 中常见的几种类型和概念——将任务隔离到不同的执行上下文中,使用通道进行任务间通信,从远程任务中提取结果等等。 在文档中了解更多信息。 分享并享受。
import Futures
// Create *executors* to spawn *tasks* on. Each QueueExecutor
// is backed by a private serial DispatchQueue.
let deepThought = (
cpu0: QueueExecutor(label: "CPU 0"),
cpu1: QueueExecutor(label: "CPU 1"),
cpu2: QueueExecutor(label: "CPU 2")
)
// Create two *channels* via which values can be communicated
// between parts of the program.
let pipe1 = Channel.makeUnbuffered(itemType: Int.self)
let pipe2 = Channel.makeUnbuffered(itemType: Int.self)
// Spawn a task that produces positive integers on one
// executor and sends the values to one of the channels.
let integers = Stream.sequence(0...)
deepThought.cpu1.submit(integers.forward(to: pipe1))
// Spawn another task on the second executor that receives
// these values, filters out non-prime integers and sends
// the remaining down the second channel.
let primes = pipe1.makeStream().filter(isPrime)
deepThought.cpu2.submit(primes.forward(to: pipe2))
// Spawn a third task on the third executor that receives
// the prime numbers via the channel and performs the actual
// computation of the answer. For this task, we ask for a
// handle back, with which we can get the final result or
// cancel it.
var answer = deepThought.cpu0.spawn(
pipe2.makeStream()
.buffer(4)
.map { $0[0] * $0[1] * $0[3] }
.first(where: isPronic)
)
// At this point, everything happens asynchronously in
// secondary background threads, so the program would just
// exit. We need the answer first however, so we block the
// current thread waiting for the result of the computation
// which we just print to standard output.
print(answer.wait()) // prints "Result.success(42)"
如果您想自己运行该程序并进行实验,则需要以下函数
import Foundation
func isPrime(_ n: Int) -> Bool {
return n == 2 || n > 2 && (2...(n - 1)).allSatisfy {
!n.isMultiple(of: $0)
}
}
func isPronic(_ n: Int) -> Bool {
let f = floor(Double(n).squareRoot())
let c = ceil(Double(n).squareRoot())
return n == Int(f) * Int(c)
}
Futures 需要 Swift 5.0 (或更高版本) 并且可以部署到以下任何平台
要将 Futures 与 Swift Package Manager 集成,请在您的 Package.swift
中的依赖项列表中添加以下行
.package(url: "https://github.com/dfunckt/swift-futures.git", .upToNextMinor(from: "0.1.0"))
注意:Futures 尚处于早期阶段,其公共 API 可能会发生重大变化。 在 1.0 版本之前,重大更改将伴随次要版本升级。
然后将 Futures 添加为您希望在其中使用的目标的依赖项。 Futures 导出两个独立的模块
Futures
:核心库。FuturesSync
:各种线程同步原语和助手。 该模块目前处于高度试验阶段,不建议使用。这是一个 Package.swift
示例
// swift-tools-version:5.0
import PackageDescription
let package = Package(
name: "MyApp",
products: [
.executable(name: "MyApp", targets: ["MyTarget"]),
],
dependencies: [
.package(url: "https://github.com/dfunckt/swift-futures.git", .upToNextMinor(from: "0.1.0")),
],
targets: [
.target(name: "MyTarget", dependencies: ["Futures"]),
]
)
Futures 在 MIT 许可的条款下获得许可。 有关详细信息,请参见 LICENSE。