我一直在探索
AsyncTimerSequence
中的 AsyncAlgorithms 并发现它是一个简单的解决方案,可以将元素从我的 wait 函数持续发送到侦听器。
我的问题是序列仅在给定的时间间隔后发出一个值。通过查看源代码我知道这是设计使然。然而,我想在某个函数开始侦听序列后立即发出一个值,然后在指定的时间间隔后发出一个值。
我想我必须创建自己的
AsyncSequence
(通过修改AsyncTimerSequence
),但我只是想知道是否有一种不涉及编写新序列创建器的解决方法。
我通过自己制作
AsyncSequence
解决了这个问题,但可能有更好的方法。
public struct AsyncInitialTimerSequence<C: Clock>: AsyncSequence {
public typealias Element = C.Instant
/// The iterator for an `AsyncInitialTimerSequence` instance.
public struct Iterator: AsyncIteratorProtocol {
var clock: C?
let interval: C.Instant.Duration
let tolerance: C.Instant.Duration?
var last: C.Instant?
init(interval: C.Instant.Duration, tolerance: C.Instant.Duration?, clock: C) {
self.clock = clock
self.interval = interval
self.tolerance = tolerance
}
public mutating func next() async -> C.Instant? {
guard let clock = self.clock else {
return nil
}
if self.last == nil {
let now = clock.now
self.last = now
return now
}
let next = (self.last ?? clock.now).advanced(by: self.interval)
do {
try await clock.sleep(until: next, tolerance: self.tolerance)
} catch {
self.clock = nil
return nil
}
let now = clock.now
self.last = next
return now
}
}
let clock: C
let interval: C.Instant.Duration
let tolerance: C.Instant.Duration?
/// Create an `AsyncInitialTimerSequence` with a given repeating interval.
public init(interval: C.Instant.Duration, tolerance: C.Instant.Duration? = nil, clock: C) {
self.clock = clock
self.interval = interval
self.tolerance = tolerance
}
public func makeAsyncIterator() -> Iterator {
Iterator(interval: interval, tolerance: tolerance, clock: clock)
}
}
extension AsyncInitialTimerSequence {
/// Create an `AsyncInitialTimerSequence` with a given repeating interval.
public static func repeating(every interval: C.Instant.Duration, tolerance: C.Instant.Duration? = nil, clock: C) -> AsyncInitialTimerSequence<C> {
return AsyncInitialTimerSequence(interval: interval, tolerance: tolerance, clock: clock)
}
}
extension AsyncInitialTimerSequence where C == SuspendingClock {
/// Create an `AsyncInitialTimerSequence` with a given repeating interval.
public static func repeating(every interval: Duration, tolerance: Duration? = nil) -> AsyncInitialTimerSequence<SuspendingClock> {
return AsyncInitialTimerSequence(interval: interval, tolerance: tolerance, clock: SuspendingClock())
}
}
extension AsyncInitialTimerSequence: Sendable { }
extension AsyncInitialTimerSequence.Iterator: Sendable { }
类似的东西?
func listen() async -> AsyncThrowingStream<Value> {
var firstTime = true
return AsyncAsyncThrowingStreamStream {
if !firstTime {
try await Task.sleep(someDuration)
}
firstTime = false
return try await emmiter()
}
}