AsyncThrowingStream
声明
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
闭包 - 在运行时调用以创建流 - 使用延续执行以下步骤:
-
创建一个
QuakeMonitor
实例。 -
将监视器的
quakeHandler
属性设置为一个闭包,该闭包接收每个Quake
实例并通过调用延续的yield(_:)
方法将其转发到流。 -
将监视器的
errorHandler
属性设置为一个闭包,该闭包从监视器接收任何错误并通过调用延续的finish(throwing:)
方法将其转发到流。这会导致流的迭代器抛出错误并终止流。 -
将延续的
onTermination
属性设置为在监视器上调用stopMonitoring()
的闭包。 -
在
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)")
}
可用版本
相关用法
- Swift AsyncThrowingStream filter(_:)用法及代码示例
- Swift AsyncThrowingStream init(unfolding:)用法及代码示例
- Swift AsyncThrowingStream max(by:)用法及代码示例
- Swift AsyncThrowingStream contains(where:)用法及代码示例
- Swift AsyncThrowingStream map(_:)用法及代码示例
- Swift AsyncThrowingStream prefix(_:)用法及代码示例
- Swift AsyncThrowingStream min(by:)用法及代码示例
- Swift AsyncThrowingStream allSatisfy(_:)用法及代码示例
- Swift AsyncThrowingStream contains(_:)用法及代码示例
- Swift AsyncThrowingStream compactMap(_:)用法及代码示例
- Swift AsyncThrowingStream reduce(_:_:)用法及代码示例
- Swift AsyncThrowingStream init(_:bufferingPolicy:_:)用法及代码示例
- Swift AsyncThrowingStream first(where:)用法及代码示例
- Swift AsyncThrowingStream drop(while:)用法及代码示例
- Swift AsyncThrowingStream flatMap(_:)用法及代码示例
- Swift AsyncThrowingStream min()用法及代码示例
- Swift AsyncThrowingStream prefix(while:)用法及代码示例
- Swift AsyncThrowingStream max()用法及代码示例
- Swift AsyncThrowingStream dropFirst(_:)用法及代码示例
- Swift AsyncThrowingFlatMapSequence min()用法及代码示例
- Swift AsyncThrowingMapSequence reduce(_:_:)用法及代码示例
- Swift AsyncThrowingPrefixWhileSequence drop(while:)用法及代码示例
- Swift AsyncThrowingMapSequence contains(_:)用法及代码示例
- Swift AsyncThrowingPrefixWhileSequence filter(_:)用法及代码示例
- Swift AsyncThrowingDropWhileSequence first(where:)用法及代码示例
注:本文由纯净天空筛选整理自apple.com大神的英文原创作品 AsyncThrowingStream。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。