Futures(未来)

Futures 是一个轻量级的、通用的 Swift 异步编程库,它提供了一组可互操作的原语,以帮助开发高度并发、高性能和安全的程序,无论是在服务器端、桌面端还是移动端。Futures 采用了一种“拉取”式、需求驱动的方法进行异步编程,除了提供惊人的性能外,还可以轻松处理诸如反压、取消和线程等传统上难以解决的问题。

文档 / 快速示例 / 要求 / 安装


为什么选择 Futures?

Swift 中已经存在大量用于异步编程的库。 许多都是优秀的库,如果您正在寻找适合您需求的抽象,您应该认真考虑它们。 那么您为什么要关心 Futures 呢?

您会发现 Futures...

特性

请继续阅读,还有更多内容

快速示例

这是一个小程序,用于计算生命、宇宙和一切的终极问题的答案

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 导出两个独立的模块

这是一个 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