當前位置: 首頁>>編程示例 >>用法及示例精選 >>正文


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。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。