当前位置: 首页>>代码示例 >>用法及示例精选 >>正文


Swift AsyncStream用法及代码示例


结构

AsyncStream

从调用延续以产生新元素的闭包生成的异步序列。

声明

struct AsyncStream<Element>

概述

AsyncStream 符合 AsyncSequence ,提供了一种方便的方法来创建异步序列,而无需手动实现异步迭代器。特别是,异步流是 well-suited 以适应基于回调或委托的 API 以参与 async - await

您使用接收 AsyncStream.Continuation 的闭包初始化 AsyncStream 。在此闭包中生成元素,然后通过调用延续的 yield(_:) 方法将它们提供给流。当没有其他元素要生成时,调用延续的 finish() 方法。这会导致序列迭代器生成 nil ,从而终止序列。延续符合 Sendable ,这允许从 AsyncStream 迭代之外的并发上下文调用它。

任意元素来源可以比调用者迭代它们消耗的更快地生成元素。因此,AsyncStream 定义了一种缓冲行为,允许流缓冲特定数量的最旧或最新元素。默认情况下,缓冲区限制为 Int.max ,这意味着该值是无界的。

调整现有代码以使用流

要调整现有回调代码以使用 async - await ,请使用回调为流提供值,方法是使用延续的 yield(_:) 方法。

考虑一个假设的 QuakeMonitor 类型,它在每次检测到地震时为调用者提供 Quake 实例。为了接收回调,调用者将自定义闭包设置为监视器的 quakeHandler 属性的值,监视器会根据需要回调该属性。


class QuakeMonitor {
    var quakeHandler: ((Quake) -> Void)?


    func startMonitoring() {…}
    func stopMonitoring() {…}
}

要使其适应使用 async - await ,请扩展 QuakeMonitor 以添加类型为 AsyncStream<Quake>quakes 属性。在此属性的 getter 中,返回一个 AsyncStream ,其 build 闭包 - 在运行时调用以创建流 - 使用延续执行以下步骤:

  1. 创建一个QuakeMonitor 实例。

  2. 将监视器的 quakeHandler 属性设置为一个闭包,该闭包接收每个 Quake 实例并通过调用延续的 yield(_:) 方法将其转发到流。

  3. 将延续的 onTermination 属性设置为在监视器上调用 stopMonitoring() 的闭包。

  4. QuakeMonitor 上调用 startMonitoring


extension QuakeMonitor {


    static var quakes: AsyncStream<Quake> {
        AsyncStream { continuation in
            let monitor = QuakeMonitor()
            monitor.quakeHandler = { quake in
                continuation.yield(quake)
            }
            continuation.onTermination = { @Sendable _ in
                 monitor.stopMonitoring()
            }
            monitor.startMonitoring()
        }
    }
}

因为流是 AsyncSequence ,所以调用点可以使用 for - await - in 语法来处理流产生的每个 Quake 实例:


for await quake in QuakeMonitor.quakes {
    print ("Quake: \(quake.date)")
}
print ("Stream finished.")

可用版本

iOS 13.0+, iPadOS 13.0+, macOS 10.15+, Mac Catalyst 13.0+, tvOS 13.0+, watchOS 6.0+

相关用法


注:本文由纯净天空筛选整理自apple.com大神的英文原创作品 AsyncStream。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。