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


Swift AsyncThrowingStream用法及代码示例


结构

AsyncThrowingStream

从 error-throwing 闭包生成的异步序列,该闭包调用延续以生成新元素。

声明

struct AsyncThrowingStream<Element, Failure> where Failure : Error

概述

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

AsyncStream 相比,此类型可以从等待的 next() 引发错误,这会终止带有引发错误的流。

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

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

调整现有代码以使用流

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

考虑一个假设的 QuakeMonitor 类型,它在每次检测到地震时为调用者提供 Quake 实例。为了接收回调,调用者将自定义闭包设置为监视器的 quakeHandler 属性的值,监视器会根据需要回调该属性。调用者还可以设置errorHandler 来接收异步错误通知,例如监控服务突然变得不可用。


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


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

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

  1. 创建一个QuakeMonitor 实例。

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

  3. 将监视器的errorHandler 属性设置为一个闭包,该闭包从监视器接收任何错误并通过调用延续的finish(throwing:) 方法将其转发到流。这会导致流的迭代器抛出错误并终止流。

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

  5. QuakeMonitor 上调用 startMonitoring


extension QuakeMonitor {


    static var throwingQuakes: AsyncThrowingStream<Quake, Error> {
        AsyncThrowingStream { continuation in
            let monitor = QuakeMonitor()
            monitor.quakeHandler = { quake in
                 continuation.yield(quake)
            }
            monitor.errorHandler = { error in
                continuation.finish(throwing: error)
            }
            continuation.onTermination = { @Sendable _ in
                monitor.stopMonitoring()
            }
            monitor.startMonitoring()
        }
    }
}

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


do {
    for try await quake in quakeStream {
        print ("Quake: \(quake.date)")
    }
    print ("Stream done.")
} catch {
    print ("Error: \(error)")
}

可用版本

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

相关用法


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